diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab
index 8dfa5c4ec4c93895262d81b6909fe54918d2cac1..c3b997a4e89e015722df42a63979073cae3f3351 100644
--- a/ci-scripts/Jenkinsfile-gitlab
+++ b/ci-scripts/Jenkinsfile-gitlab
@@ -66,7 +66,8 @@ pipeline {
             "Test-IF4p5-TDD-Band38-Multi-RRU",
             "Test-eNB-OAI-UE-FDD-Band7",
             "Test-Mono-FDD-Band13-X2-HO",
-            "Test-TDD-Band78-gNB-NR-UE"
+            "Test-TDD-Band78-gNB-NR-UE",
+            "Test-OCP-FDD-Band7"
         ])
         ansiColor('xterm')
     }
@@ -683,6 +684,25 @@ pipeline {
                         }
                     }
                 }
+                stage ("Test OAI OCP-eNB - FDD - Band 7 - B210") {
+                    steps {
+                        script {
+                            triggerSlaveJob ('OCPeNB-FDD-Band7-B210', 'Test-OCP-FDD-Band7')
+                        }
+                    }
+                    post {
+                        always {
+                            script {
+                                finalizeSlaveJob('OCPeNB-FDD-Band7-B210')
+                            }
+                        }
+                        failure {
+                            script {
+                                currentBuild.result = 'FAILURE'
+                            }
+                        }
+                    }
+                }
             }
             post {
                 always {
diff --git a/ci-scripts/args_parse.py b/ci-scripts/args_parse.py
new file mode 100644
index 0000000000000000000000000000000000000000..1249f521728c1e846f7dfb8871185d966292aa40
--- /dev/null
+++ b/ci-scripts/args_parse.py
@@ -0,0 +1,229 @@
+
+# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+# * contributor license agreements.  See the NOTICE file distributed with
+# * this work for additional information regarding copyright ownership.
+# * The OpenAirInterface Software Alliance licenses this file to You under
+# * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+# * except in compliance with the License.
+# * You may obtain a copy of the License at
+# *
+# *      http://www.openairinterface.org/?page_id=698
+# *
+# * Unless required by applicable law or agreed to in writing, software
+# * distributed under the License is distributed on an "AS IS" BASIS,
+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# * See the License for the specific language governing permissions and
+# * limitations under the License.
+# *-------------------------------------------------------------------------------
+# * For more information about the OpenAirInterface (OAI) Software Alliance:
+# *      contact@openairinterface.org
+# */
+#---------------------------------------------------------------------
+# Python for CI of OAI-eNB + COTS-UE
+#
+#   Required Python Version
+#     Python 3.x
+#
+#   Required Python Package
+#     pexpect
+#---------------------------------------------------------------------
+
+#-----------------------------------------------------------
+# Import Libs
+#-----------------------------------------------------------
+import sys		# arg
+import re		# reg
+import yaml
+
+
+#-----------------------------------------------------------
+# Parsing Command Line Arguements
+#-----------------------------------------------------------
+
+
+def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,HELP):
+
+
+    py_param_file_present = False
+    py_params={}
+
+    while len(argvs) > 1:
+        myArgv = argvs.pop(1)	# 0th is this file's name
+
+	    #--help
+        if re.match('^\-\-help$', myArgv, re.IGNORECASE):
+            HELP.GenericHelp(CONST.Version)
+            sys.exit(0)
+
+	    #--apply=<filename> as parameters file, to replace inline parameters
+        elif re.match('^\-\-Apply=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-Apply=(.+)$', myArgv, re.IGNORECASE)
+            py_params_file = matchReg.group(1)
+            with open(py_params_file,'r') as file:
+          	# The FullLoader parameter handles the conversion from YAML
+        	# scalar values to Python dictionary format
+                py_params = yaml.load(file,Loader=yaml.FullLoader)
+                py_param_file_present = True #to be removed once validated
+	    		#AssignParams(py_params) #to be uncommented once validated
+
+	    #consider inline parameters
+        elif re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE)
+            mode = matchReg.group(1)
+        elif re.match('^\-\-eNBRepository=(.+)$|^\-\-ranRepository(.+)$', myArgv, re.IGNORECASE):
+            if re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE):
+                matchReg = re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE)
+            else:
+                matchReg = re.match('^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE)
+            CiTestObj.ranRepository = matchReg.group(1)
+            RAN.ranRepository=matchReg.group(1)
+            HTML.ranRepository=matchReg.group(1)
+            ldpc.ranRepository=matchReg.group(1)
+        elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE):
+            if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE):
+                matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE)
+            else:
+                matchReg = re.match('^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE)
+            doMerge = matchReg.group(1)
+            ldpc.ranAllowMerge=matchReg.group(1)
+            if ((doMerge == 'true') or (doMerge == 'True')):
+                CiTestObj.ranAllowMerge = True
+                RAN.ranAllowMerge=True
+                HTML.ranAllowMerge=True
+        elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE):
+            if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE):
+                matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE)
+            else:
+                matchReg = re.match('^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE)
+            CiTestObj.ranBranch = matchReg.group(1)
+            RAN.ranBranch=matchReg.group(1)
+            HTML.ranBranch=matchReg.group(1)
+            ldpc.ranBranch=matchReg.group(1)
+        elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE):
+            if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE):
+                matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE)
+            else:
+                matchReg = re.match('^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE)
+            CiTestObj.ranCommitID = matchReg.group(1)
+            RAN.ranCommitID=matchReg.group(1)
+            HTML.ranCommitID=matchReg.group(1)
+            ldpc.ranCommitID=matchReg.group(1)
+        elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE):
+            if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE):
+                matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE)
+            else:
+                matchReg = re.match('^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE)
+            CiTestObj.ranTargetBranch = matchReg.group(1)
+            RAN.ranTargetBranch=matchReg.group(1)
+            HTML.ranTargetBranch=matchReg.group(1)
+            ldpc.ranTargetBranch=matchReg.group(1)
+        elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE):
+            if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE):
+                matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE)
+                RAN.eNBIPAddress=matchReg.group(1)
+                ldpc.eNBIpAddr=matchReg.group(1)
+            elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE):
+                matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE)
+                RAN.eNB1IPAddress=matchReg.group(1)
+            elif re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE):
+                matchReg = re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE)
+                RAN.eNB2IPAddress=matchReg.group(1)
+        elif re.match('^\-\-eNBUserName=(.+)$|^\-\-eNB[1-2]UserName=(.+)$', myArgv, re.IGNORECASE):
+            if re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE):
+                matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE)
+                RAN.eNBUserName=matchReg.group(1)
+                ldpc.eNBUserName=matchReg.group(1)
+            elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE):
+                matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE)
+                RAN.eNB1UserName=matchReg.group(1)
+            elif re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE):
+                matchReg = re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE)
+                RAN.eNB2UserName=matchReg.group(1)
+        elif re.match('^\-\-eNBPassword=(.+)$|^\-\-eNB[1-2]Password=(.+)$', myArgv, re.IGNORECASE):
+            if re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE):
+                matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE)
+                RAN.eNBPassword=matchReg.group(1)
+                ldpc.eNBPassWord=matchReg.group(1)
+            elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE):
+                matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE)
+                RAN.eNB1Password=matchReg.group(1)
+            elif re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE):
+                matchReg = re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE)
+                RAN.eNB2Password=matchReg.group(1)
+        elif re.match('^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
+            if re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE):
+                matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE)
+                RAN.eNBSourceCodePath=matchReg.group(1)
+                ldpc.eNBSourceCodePath=matchReg.group(1)
+            elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
+                matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
+                RAN.eNB1SourceCodePath=matchReg.group(1)
+            elif re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
+                matchReg = re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
+                RAN.eNB2SourceCodePath=matchReg.group(1)
+        elif re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE)
+            EPC.IPAddress=matchReg.group(1)
+        elif re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE)
+            EPC.UserName=matchReg.group(1)
+        elif re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE)
+            EPC.Password=matchReg.group(1)
+        elif re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE)
+            EPC.SourceCodePath=matchReg.group(1)
+        elif re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE)
+            if re.match('OAI', matchReg.group(1), re.IGNORECASE) or re.match('ltebox', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-CUPS', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-Docker', matchReg.group(1), re.IGNORECASE):
+                EPC.Type=matchReg.group(1)
+            else:
+                sys.exit('Invalid EPC Type: ' + matchReg.group(1) + ' -- (should be OAI or ltebox or OAI-Rel14-CUPS or OAI-Rel14-Docker)')
+        elif re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE)
+            EPC.ContainerPrefix=matchReg.group(1)
+        elif re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE)
+            CiTestObj.ADBIPAddress = matchReg.group(1)
+        elif re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE)
+            CiTestObj.ADBUserName = matchReg.group(1)
+        elif re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE)
+            if re.match('centralized', matchReg.group(1), re.IGNORECASE) or re.match('distributed', matchReg.group(1), re.IGNORECASE):
+                if re.match('distributed', matchReg.group(1), re.IGNORECASE):
+                    CiTestObj.ADBCentralized = False
+                else:
+                    CiTestObj.ADBCentralized = True
+            else:
+                sys.exit('Invalid ADB Type: ' + matchReg.group(1) + ' -- (should be centralized or distributed)')
+        elif re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE)
+            CiTestObj.ADBPassword = matchReg.group(1)
+        elif re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE)
+            CiTestObj.testXMLfiles.append(matchReg.group(1))
+            HTML.testXMLfiles.append(matchReg.group(1))
+            HTML.nbTestXMLfiles=HTML.nbTestXMLfiles+1
+        elif re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE)
+            CiTestObj.UEIPAddress = matchReg.group(1)
+        elif re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE)
+            CiTestObj.UEUserName = matchReg.group(1)
+        elif re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE)
+            CiTestObj.UEPassword = matchReg.group(1)
+        elif re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE)
+            CiTestObj.UESourceCodePath = matchReg.group(1)
+        elif re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE)
+            finalStatus = matchReg.group(1)
+            if ((finalStatus == 'true') or (finalStatus == 'True')):
+                CiTestObj.finalStatus = True
+        else:
+            HELP.GenericHelp(CONST.Version)
+            sys.exit('Invalid Parameter: ' + myArgv)
+
+    return py_param_file_present, py_params, mode
diff --git a/ci-scripts/cls_cots_ue.py b/ci-scripts/cls_cots_ue.py
new file mode 100644
index 0000000000000000000000000000000000000000..6954aa392742f1ca77ee64d46e97b468a2614cff
--- /dev/null
+++ b/ci-scripts/cls_cots_ue.py
@@ -0,0 +1,88 @@
+# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+# * contributor license agreements.  See the NOTICE file distributed with
+# * this work for additional information regarding copyright ownership.
+# * The OpenAirInterface Software Alliance licenses this file to You under
+# * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+# * except in compliance with the License.
+# * You may obtain a copy of the License at
+# *
+# *      http://www.openairinterface.org/?page_id=698
+# *
+# * Unless required by applicable law or agreed to in writing, software
+# * distributed under the License is distributed on an "AS IS" BASIS,
+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# * See the License for the specific language governing permissions and
+# * limitations under the License.
+# *-------------------------------------------------------------------------------
+# * For more information about the OpenAirInterface (OAI) Software Alliance:
+# *      contact@openairinterface.org
+# */
+#---------------------------------------------------------------------
+# Python for CI of OAI-eNB + COTS-UE
+#
+#   Required Python Version
+#     Python 3.x
+#
+#   Required Python Package
+#     pexpect
+#---------------------------------------------------------------------
+
+#to use logging.info()
+import logging
+#to create a SSH object locally in the methods
+import sshconnection
+#time.sleep
+import time
+
+class CotsUe:
+	def __init__(self,model,UEIPAddr,UEUserName,UEPassWord):
+		self.model = model
+		self.UEIPAddr = UEIPAddr 
+		self.UEUserName = UEUserName
+		self.UEPassWord = UEPassWord
+		self.runargs = '' #on of off to toggle airplane mode on/off
+		self.__SetAirplaneRetry = 3
+
+#-----------------$
+#PUBLIC Methods$
+#-----------------$
+
+	def Check_Airplane(self):
+		mySSH = sshconnection.SSHConnection()
+		mySSH.open(self.UEIPAddr, self.UEUserName, self.UEPassWord)
+		status=mySSH.cde_check_value('sudo adb shell settings get global airplane_mode_on ', ['0','1'],5)
+		mySSH.close()
+		return status
+
+
+	def Set_Airplane(self,target_state_str):
+		mySSH = sshconnection.SSHConnection()
+		mySSH.open(self.UEIPAddr, self.UEUserName, self.UEPassWord)
+		mySSH.command('sudo adb start-server','$',5)
+		logging.info("Toggling COTS UE Airplane mode to : "+target_state_str)
+		current_state = self.Check_Airplane()
+		if target_state_str.lower()=="on": 
+			target_state=1
+		else:
+			target_state=0
+		if current_state != target_state:
+			#toggle state
+			retry = 0 
+			while (current_state!=target_state) and (retry < self.__SetAirplaneRetry):
+				mySSH.command('sudo adb shell am start -a android.settings.AIRPLANE_MODE_SETTINGS', '\$', 5)
+				mySSH.command('sudo adb shell input keyevent 20', '\$', 5)
+				mySSH.command('sudo adb shell input tap 968 324', '\$', 5)
+				time.sleep(1)
+				current_state = self.Check_Airplane()
+				retry+=1
+			if current_state != target_state:
+				logging.error("ATTENTION : Could not toggle to : "+target_state_str)
+				logging.error("Current state is : "+ str(current_state))
+		else:
+			print("Airplane mode is already "+ target_state_str)
+		mySSH.command('sudo adb kill-server','$',5)
+		mySSH.close()
+
+
+
+
diff --git a/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf
new file mode 100755
index 0000000000000000000000000000000000000000..5b2c90a714d773e456215098095edfd569a428fd
--- /dev/null
+++ b/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf
@@ -0,0 +1,284 @@
+Active_eNBs = ( "eNB-Eurecom-LTEBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+eNBs =
+(
+ {
+    # real_time choice in {hard, rt-preempt, no}
+    real_time       =  "no";
+    ////////// Identification parameters:
+    eNB_ID    =  0xe01;
+    cell_type =  "CELL_MACRO_ENB";
+    eNB_name  =  "eNB-Eurecom-LTEBox";
+    
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  1;
+    plmn_list = (
+      { mcc = 222; mnc = 01; mnc_length = 2; }
+    );
+    
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+  
+    component_carriers = (
+      {
+        node_function                    = "eNodeB_3GPP";
+        node_timing                      = "synch_to_ext_device";
+        node_synch_ref                   = 0;
+        nb_antenna_ports                 = 1;
+        ue_TransmissionMode              = 1;
+        frame_type                       = "FDD"; 
+        tdd_config                       = 3;
+        tdd_config_s                     = 0;
+        prefix_type                      = "NORMAL";
+        eutra_band                       = 7;
+        downlink_frequency               = 2680000000L;
+        uplink_frequency_offset          = -120000000;
+  
+        Nid_cell                         = 0;
+        N_RB_DL                          = 25;
+        Nid_cell_mbsfn                   = 0;
+        nb_antennas_tx                   = 1;
+        nb_antennas_rx                   = 1; 
+        prach_root                       = 0;
+        tx_gain                          = 90;
+        rx_gain                          = 115;
+        pbch_repetition                  = "FALSE";
+
+        prach_config_index               = 0;
+        prach_high_speed                 = "DISABLE";
+        prach_zero_correlation           = 1;
+        prach_freq_offset                = 2;
+
+        pucch_delta_shift                = 1;
+        pucch_nRB_CQI                    = 0;
+        pucch_nCS_AN                     = 0;
+        pucch_n1_AN                      = 0;
+        pdsch_referenceSignalPower       = -29;
+        pdsch_p_b                        = 0;
+        pusch_n_SB                       = 1; 
+        pusch_enable64QAM                = "DISABLE";
+        pusch_hoppingMode                = "interSubFrame";
+        pusch_hoppingOffset              = 0;
+        pusch_groupHoppingEnabled        = "ENABLE";
+        pusch_groupAssignment            = 0;
+        pusch_sequenceHoppingEnabled     = "DISABLE";
+        pusch_nDMRS1                     = 1;
+        phich_duration                   = "NORMAL";
+        phich_resource                   = "ONESIXTH";
+        srs_enable                       = "DISABLE";
+/*
+        srs_BandwidthConfig              =;
+        srs_SubframeConfig               =;
+        srs_ackNackST                    =;
+        srs_MaxUpPts                     =;
+*/
+
+        pusch_p0_Nominal                 = -96;
+        pusch_alpha                      = "AL1";
+        pucch_p0_Nominal                 = -96;
+        msg3_delta_Preamble              = 6;
+        pucch_deltaF_Format1             = "deltaF2";
+        pucch_deltaF_Format1b            = "deltaF3";
+        pucch_deltaF_Format2             = "deltaF0";
+        pucch_deltaF_Format2a            = "deltaF0";
+        pucch_deltaF_Format2b            = "deltaF0";
+ 
+        rach_numberOfRA_Preambles        = 64;
+        rach_preamblesGroupAConfig       = "DISABLE";
+/*
+        rach_sizeOfRA_PreamblesGroupA    = ;
+        rach_messageSizeGroupA           = ;
+        rach_messagePowerOffsetGroupB    = ; 
+*/
+        rach_powerRampingStep                   = 4;
+        rach_preambleInitialReceivedTargetPower = -108;
+        rach_preambleTransMax                   = 10;
+        rach_raResponseWindowSize               = 10;
+        rach_macContentionResolutionTimer       = 48;
+        rach_maxHARQ_Msg3Tx                     = 4;
+
+      pcch_default_PagingCycle           = 128;
+      pcch_nB                            = "oneT";
+      bcch_modificationPeriodCoeff       = 2;
+      ue_TimersAndConstants_t300         = 1000;
+      ue_TimersAndConstants_t301         = 1000;
+      ue_TimersAndConstants_t310         = 1000;
+      ue_TimersAndConstants_t311         = 10000;
+      ue_TimersAndConstants_n310         = 20;
+      ue_TimersAndConstants_n311         = 1;
+
+      //Parameters for SIB18
+      rxPool_sc_CP_Len                                       = "normal"; 
+      rxPool_sc_Period                                       = "sf40";  
+      rxPool_data_CP_Len                                     = "normal";  
+      rxPool_ResourceConfig_prb_Num                          = 20;
+      rxPool_ResourceConfig_prb_Start                        = 5;
+      rxPool_ResourceConfig_prb_End                          = 44;
+      rxPool_ResourceConfig_offsetIndicator_present          = "prSmall";
+      rxPool_ResourceConfig_offsetIndicator_choice           = 0;      
+      rxPool_ResourceConfig_subframeBitmap_present           = "prBs40";
+      rxPool_ResourceConfig_subframeBitmap_choice_bs_buf              = "00000000000000000000";
+      rxPool_ResourceConfig_subframeBitmap_choice_bs_size             = 5;
+      rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused      = 0;
+/*
+      rxPool_dataHoppingConfig_hoppingParameter                       = 0;
+      rxPool_dataHoppingConfig_numSubbands                            = "ns1";
+      rxPool_dataHoppingConfig_rbOffset                               = 0;
+      rxPool_commTxResourceUC-ReqAllowed                              = "TRUE";
+*/    
+      // Parameters for SIB19
+      discRxPool_cp_Len                                               = "normal"
+      discRxPool_discPeriod                                           = "rf32"
+      discRxPool_numRetx                                              = 1;   
+      discRxPool_numRepetition                                        = 2;
+      discRxPool_ResourceConfig_prb_Num                               = 5;  
+      discRxPool_ResourceConfig_prb_Start                             = 3;
+      discRxPool_ResourceConfig_prb_End                               = 21;
+      discRxPool_ResourceConfig_offsetIndicator_present               = "prSmall";
+      discRxPool_ResourceConfig_offsetIndicator_choice                = 0;      
+      discRxPool_ResourceConfig_subframeBitmap_present                = "prBs40";
+      discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf          = "f0ffffffff";
+      discRxPool_ResourceConfig_subframeBitmap_choice_bs_size         = 5;
+      discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused  = 0;
+
+    }
+  );
+
+    srb1_parameters :
+    {
+        # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
+        timer_poll_retransmit    = 80;
+
+        # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
+        timer_reordering         = 35;
+
+        # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
+        timer_status_prohibit    = 0;
+
+        # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
+        poll_pdu                 =  4;
+
+        # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
+        poll_byte                =  99999;
+
+        # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
+        max_retx_threshold       =  4;
+    }
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+    enable_measurement_reports = "yes";
+
+    ////////// MME parameters:
+    mme_ip_address      = ( { ipv4       = "CI_MME_IP_ADDR";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    ///X2
+    enable_x2 = "yes";
+    t_reloc_prep      = 1000;      /* unit: millisecond */
+    tx2_reloc_overall = 2000;      /* unit: millisecond */
+
+    NETWORK_INTERFACES : 
+    {
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "eth1";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "CI_ENB_IP_ADDR";
+
+        ENB_INTERFACE_NAME_FOR_S1U               = "eth1";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "CI_ENB_IP_ADDR";
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
+
+        ENB_IPV4_ADDRESS_FOR_X2C                 = "CI_ENB_IP_ADDR";
+        ENB_PORT_FOR_X2C                         = 36422; # Spec 36422
+    };
+    
+    log_config : 
+    {
+     global_log_level                      ="info"; 
+     global_log_verbosity                  ="high";
+     hw_log_level                          ="info"; 
+     hw_log_verbosity                      ="medium";
+     phy_log_level                         ="info"; 
+     phy_log_verbosity                     ="medium";
+     mac_log_level                         ="info"; 
+     mac_log_verbosity                     ="high";
+     rlc_log_level                         ="debug"; 
+     rlc_log_verbosity                     ="high";
+     pdcp_log_level                        ="info"; 
+     pdcp_log_verbosity                    ="high";
+     rrc_log_level                         ="info"; 
+     rrc_log_verbosity                     ="medium";
+   }; 
+   
+  }
+);
+
+MACRLCs = (
+  {
+    num_cc          = 1;
+    tr_s_preference = "local_L1";
+    tr_n_preference = "local_RRC";
+    phy_test_mode   = 0;
+    puSch10xSnr     =  160;
+    puCch10xSnr     =  160;
+  }  
+);
+
+THREAD_STRUCT = (
+  {
+    parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
+    worker_config   = "ENABLE";
+  }
+);
+
+L1s = (
+  {
+    num_cc          = 1;
+    tr_n_preference = "local_mac";
+  }  
+);
+
+RUs = (
+  {             
+    local_rf       = "yes"
+    nb_tx          = 1
+    nb_rx          = 1
+    att_tx         = 0
+    att_rx         = 0;
+    bands          = [7];
+    max_pdschReferenceSignalPower = -27;
+    max_rxgain                    = 118;
+    eNB_instances  = [0];
+    clock_src      = "external";
+  }
+);  
+
+log_config : 
+  {
+     global_log_level                      ="info"; 
+     global_log_verbosity                  ="high";
+     hw_log_level                          ="info"; 
+     hw_log_verbosity                      ="medium";
+     phy_log_level                         ="info"; 
+     phy_log_verbosity                     ="medium";
+     mac_log_level                         ="info"; 
+     mac_log_verbosity                     ="high";
+     rlc_log_level                         ="info"; 
+     rlc_log_verbosity                     ="high";
+     pdcp_log_level                        ="info"; 
+     pdcp_log_verbosity                    ="high";
+     rrc_log_level                         ="info"; 
+     rrc_log_verbosity                     ="medium";
+  }; 
diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
new file mode 100755
index 0000000000000000000000000000000000000000..92af74c300248c020bc8ebedca4b5fc9e62c1f5e
--- /dev/null
+++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
@@ -0,0 +1,291 @@
+Active_gNBs = ( "gNB-Eurecom-5GNRBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+gNBs =
+(
+ {
+    ////////// Identification parameters:
+    gNB_ID    =  0xe00;
+
+    cell_type =  "CELL_MACRO_GNB";
+    gNB_name  =  "gNB-Eurecom-5GNRBox";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  1;
+    plmn_list = ({mcc = 222; mnc = 01; mnc_length = 2;});   
+
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 31; //0;
+    pdsch_AntennaPorts                                        = 1;
+  
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                          = 641272; //641032;      #641968; 641968=start of ssb at 3600MHz + 82 RBs    641032=center of SSB at center of cell
+      dl_frequencyBand                                                 = 78;
+      # this is 3600 MHz
+      dl_absoluteFrequencyPointA                                       = 640000;
+      #scs-SpecificCarrierList
+        dl_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        dl_subcarrierSpacing                                           = 1;
+        dl_carrierBandwidth                                            = 106;
+     #initialDownlinkBWP
+      #genericParameters
+        # this is RBstart=84,L=13 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 6366; //28875; //6366; #6407; #3384;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialDLBWPsubcarrierSpacing                                           = 1;
+      #pdcch-ConfigCommon
+        initialDLBWPcontrolResourceSetZero                                      = 0;
+        initialDLBWPsearchSpaceZero                                             = 0;
+      #pdsch-ConfigCommon
+        #pdschTimeDomainAllocationList (up to 16 entries)
+             initialDLBWPk0_0                    = 0;
+             #initialULBWPmappingType
+       #0=typeA,1=typeB
+             initialDLBWPmappingType_0           = 0;
+             #this is SS=1,L=13
+             initialDLBWPstartSymbolAndLength_0  = 40;
+
+             initialDLBWPk0_1                    = 0;
+             initialDLBWPmappingType_1           = 0;
+             #this is SS=2,L=12 
+             initialDLBWPstartSymbolAndLength_1  = 53;
+
+             initialDLBWPk0_2                    = 0;
+             initialDLBWPmappingType_2           = 0;
+             #this is SS=1,L=12 
+             initialDLBWPstartSymbolAndLength_2  = 54;
+
+             initialDLBWPk0_3                    = 0;
+             initialDLBWPmappingType_3           = 0;
+             #this is SS=1,L=4 //5 (4 is for 43, 5 is for 57)
+             initialDLBWPstartSymbolAndLength_3  = 57; //43; //57;
+  #uplinkConfigCommon 
+     #frequencyInfoUL
+      ul_frequencyBand                                                 = 78;
+      #scs-SpecificCarrierList
+      ul_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      ul_subcarrierSpacing                                           = 1;
+      ul_carrierBandwidth                                            = 106;
+      pMax                                                          = 20;
+     #initialUplinkBWP
+      #genericParameters
+        initialULBWPlocationAndBandwidth                                        = 6366; //28875; //6366; #6407; #3384;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialULBWPsubcarrierSpacing                                           = 1;
+      #rach-ConfigCommon
+        #rach-ConfigGeneric
+          prach_ConfigurationIndex                                  = 98;
+#prach_msg1_FDM
+#0 = one, 1=two, 2=four, 3=eight
+          prach_msg1_FDM                                            = 0;
+          prach_msg1_FrequencyStart                                 = 0;
+          zeroCorrelationZoneConfig                                 = 13;
+          preambleReceivedTargetPower                               = -100;
+#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
+          preambleTransMax                                          = 6;
+#powerRampingStep
+# 0=dB0,1=dB2,2=dB4,3=dB6
+        powerRampingStep                                            = 1;
+#ra_ReponseWindow
+#1,2,4,8,10,20,40,80
+        ra_ResponseWindow                                           = 5;
+#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR                = 4;
+#oneHalf (0..15) 4,8,12,16,...60,64
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB                   = 14; //15;
+#ra_ContentionResolutionTimer
+#(0..7) 8,16,24,32,40,48,56,64
+        ra_ContentionResolutionTimer                                = 7;
+        rsrp_ThresholdSSB                                           = 19;
+#prach-RootSequenceIndex_PR
+#1 = 839, 2 = 139
+        prach_RootSequenceIndex_PR                                  = 2;
+        prach_RootSequenceIndex                                     = 1;
+        # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
+        #  
+        msg1_SubcarrierSpacing                                      = 1,
+
+# restrictedSetConfig
+# 0=unrestricted, 1=restricted type A, 2=restricted type B
+        restrictedSetConfig                                         = 0,
+      # pusch-ConfigCommon (up to 16 elements)
+        initialULBWPk2_0                      = 2;
+        initialULBWPmappingType_0             = 1
+        # this is SS=0 L=11
+        initialULBWPstartSymbolAndLength_0    = 55;
+   
+  initialULBWPk2_1                      = 2;
+        initialULBWPmappingType_1             = 1;
+        # this is SS=0 L=12
+        initialULBWPstartSymbolAndLength_1    = 69;
+
+        initialULBWPk2_2                      = 7;
+        initialULBWPmappingType_2             = 1;
+        # this is SS=10 L=4
+        initialULBWPstartSymbolAndLength_2    = 52;
+
+        msg3_DeltaPreamble                                          = 1;
+        p0_NominalWithGrant                                         =-90;
+
+# pucch-ConfigCommon setup :
+# pucchGroupHopping
+# 0 = neither, 1= group hopping, 2=sequence hopping
+        pucchGroupHopping                                           = 0;
+        hoppingId                                                   = 40;
+        p0_nominal                                                  = -90;
+# ssb_PositionsInBurs_BitmapPR
+# 1=short, 2=medium, 3=long
+      ssb_PositionsInBurst_PR                                       = 2;
+      ssb_PositionsInBurst_Bitmap                                   = 1; #0x80;
+
+# ssb_periodicityServingCell
+# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 
+      ssb_periodicityServingCell                                    = 2;
+
+# dmrs_TypeA_position
+# 0 = pos2, 1 = pos3
+      dmrs_TypeA_Position                                           = 0;
+
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      subcarrierSpacing                                             = 1;
+
+
+  #tdd-UL-DL-ConfigurationCommon
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      referenceSubcarrierSpacing                                    = 1;
+      # pattern1 
+      # dl_UL_TransmissionPeriodicity
+      # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
+      dl_UL_TransmissionPeriodicity                                 = 6;
+      nrofDownlinkSlots                                             = 7; //8; //7;
+      nrofDownlinkSymbols                                           = 6; //0; //6;
+      nrofUplinkSlots                                               = 2;
+      nrofUplinkSymbols                                             = 4; //0; //4;
+
+  ssPBCH_BlockPower                                             = -25;
+  }
+
+  );
+
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+
+    ////////// MME parameters:
+    mme_ip_address      = ( { ipv4       = "CI_MME_IP_ADDR";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    ///X2
+    enable_x2 = "yes";
+    t_reloc_prep      = 1000;      /* unit: millisecond */
+    tx2_reloc_overall = 2000;      /* unit: millisecond */
+    target_enb_x2_ip_address      = (
+                                     { ipv4       = "CI_FR1_CTL_ENB_IP_ADDR";
+                                       ipv6       = "192:168:30::17";
+                                       preference = "ipv4";
+                                     }
+                                    );
+
+    NETWORK_INTERFACES :
+    {
+
+        GNB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
+        GNB_IPV4_ADDRESS_FOR_S1_MME              = "CI_GNB_IP_ADDR";
+        GNB_INTERFACE_NAME_FOR_S1U               = "eth0";
+        GNB_IPV4_ADDRESS_FOR_S1U                 = "CI_GNB_IP_ADDR";
+        GNB_PORT_FOR_S1U                         = 2152; # Spec 2152
+        GNB_IPV4_ADDRESS_FOR_X2C                 = "CI_GNB_IP_ADDR";
+        GNB_PORT_FOR_X2C                         = 36422; # Spec 36422
+    };
+  }
+);
+
+MACRLCs = (
+  {
+  num_cc = 1;
+  tr_s_preference = "local_L1";
+  tr_n_preference = "local_RRC";
+        }  
+);
+
+L1s = (
+      {
+  num_cc = 1;
+  tr_n_preference = "local_mac";
+        }  
+);
+
+RUs = (
+    {      
+       local_rf       = "yes"
+         nb_tx          = 1
+         nb_rx          = 1
+         att_tx         = 0
+         att_rx         = 0;
+         bands          = [7];
+         max_pdschReferenceSignalPower = -27;
+         max_rxgain                    = 114;
+         eNB_instances  = [0];
+         clock_src = "external";
+    }
+);  
+
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    //parallel_config    = "PARALLEL_SINGLE_THREAD";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
+     log_config :
+     {
+       global_log_level                      ="info";
+       global_log_verbosity                  ="medium";
+       hw_log_level                          ="info";
+       hw_log_verbosity                      ="medium";
+       phy_log_level                         ="info";
+       phy_log_verbosity                     ="medium";
+       mac_log_level                         ="info";
+       mac_log_verbosity                     ="high";
+       rlc_log_level                         ="info";
+       rlc_log_verbosity                     ="medium";
+       pdcp_log_level                        ="info";
+       pdcp_log_verbosity                    ="medium";
+       rrc_log_level                         ="info";
+       rrc_log_verbosity                     ="medium";
+    };
+
diff --git a/ci-scripts/epc.py b/ci-scripts/epc.py
index 09d500f203d185fc00fd0778721a1b5e542d4a38..25bbbba091b3ad6b65ed8e5b0a976e883de06a4b 100644
--- a/ci-scripts/epc.py
+++ b/ci-scripts/epc.py
@@ -66,38 +66,6 @@ class EPCManagement():
 		self.MmeIPAddress = ''
 		self.containerPrefix = 'prod'
 
-#-----------------------------------------------------------
-# Setter and Getters on Public Members
-#-----------------------------------------------------------
-
-	def SetIPAddress(self, ipaddress):
-		self.IPAddress = ipaddress
-	def GetIPAddress(self):
-		return self.IPAddress
-	def SetUserName(self, username):
-		self.UserName = username
-	def GetUserName(self):
-		return self.UserName
-	def SetPassword(self, password):
-		self.Password = password
-	def GetPassword(self):
-		return self.Password
-	def SetSourceCodePath(self, sourcecodepath):
-		self.SourceCodePath = sourcecodepath
-	def GetSourceCodePath(self):
-		return self.SourceCodePath
-	def SetType(self, kind):
-		self.Type = kind
-	def GetType(self):
-		return self.Type
-	def SetHtmlObj(self, obj):
-		self.htmlObj = obj
-	def SetTestCase_id(self, idx):
-		self.testCase_id = idx
-	def GetMmeIPAddress(self):
-		return self.MmeIPAddress
-	def SetContainerPrefix(self, prefix):
-		self.containerPrefix = prefix
 
 #-----------------------------------------------------------
 # EPC management functions
diff --git a/ci-scripts/html.py b/ci-scripts/html.py
index 8fa99fa61b0be9890c60dd06e46cfa690a7287c8..8f2d38cced95600c4ae587ba65aab2f871d3edc5 100644
--- a/ci-scripts/html.py
+++ b/ci-scripts/html.py
@@ -82,73 +82,14 @@ class HTMLManagement():
 #-----------------------------------------------------------
 # Setters and Getters
 #-----------------------------------------------------------
-	def SethtmlUEFailureMsg(self,huefa):
-		self.htmlUEFailureMsg = huefa
-	def GethtmlUEFailureMsg(self):
-		return self.htmlUEFailureMsg
-	def SetHmleNBFailureMsg(self, msg):
-		self.htmleNBFailureMsg = msg
-
-	def Setdesc(self, dsc):
-		self.desc = dsc
-
-	def SetstartTime(self, sttime):
-		self.startTime = sttime
-
-	def SettestCase_id(self, tcid):
-		self.testCase_id = tcid
-	def GettestCase_id(self):
-		return self.testCase_id
-
-	def SetranRepository(self, repository):
-		self.ranRepository = repository
-	def SetranAllowMerge(self, merge):
-		self.ranAllowMerge = merge
-	def SetranBranch(self, branch):
-		self.ranBranch = branch
-	def SetranCommitID(self, commitid):
-		self.ranCommitID = commitid
-	def SetranTargetBranch(self, tbranch):
-		self.ranTargetBranch = tbranch
-
+	
 	def SethtmlUEConnected(self, nbUEs):
 		if nbUEs > 0:
 			self.htmlUEConnected = nbUEs
 		else:
 			self.htmlUEConnected = 1
-	def SethtmlNb_Smartphones(self, nbUEs):
-		self.htmlNb_Smartphones = nbUEs
-	def SethtmlNb_CATM_Modules(self, nbUEs):
-		self.htmlNb_CATM_Modules = nbUEs
-
-	def SetnbTestXMLfiles(self, nb):
-		self.nbTestXMLfiles = nb
-	def GetnbTestXMLfiles(self):
-		return self.nbTestXMLfiles
-
-	def SettestXMLfiles(self, xmlFile):
-		self.testXMLfiles.append(xmlFile)
-	def SethtmlTabRefs(self, tabRef):
-		self.htmlTabRefs.append(tabRef)
-	def SethtmlTabNames(self, tabName):
-		self.htmlTabNames.append(tabName)
-	def SethtmlTabIcons(self, tabIcon):
-		self.htmlTabIcons.append(tabIcon)
+	
 
-	def SetOsVersion(self, version, idx):
-		self.OsVersion[idx] = version
-	def SetKernelVersion(self, version, idx):
-		self.KernelVersion[idx] = version
-	def SetUhdVersion(self, version, idx):
-		self.UhdVersion[idx] = version
-	def SetUsrpBoard(self, version, idx):
-		self.UsrpBoard[idx] = version
-	def SetCpuNb(self, nb, idx):
-		self.CpuNb[idx] = nb
-	def SetCpuModel(self, model, idx):
-		self.CpuModel[idx] = model
-	def SetCpuMHz(self, freq, idx):
-		self.CpuMHz[idx] = freq
 
 #-----------------------------------------------------------
 # HTML structure creation functions
diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index 63358eca38a8f3c79d17db1037daa6702d06c780..d37f205f4e6a11cb72ebacb3455613b52b21d2f9 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -1,4 +1,4 @@
-
+#/*
 # * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 # * contributor license agreements.  See the NOTICE file distributed with
 # * this work for additional information regarding copyright ownership.
@@ -28,15 +28,30 @@
 #     pexpect
 #---------------------------------------------------------------------
 
+
+
+#-----------------------------------------------------------
+# Import Components
+#-----------------------------------------------------------
+
+import helpreadme as HELP
 import constants as CONST
 
+import cls_physim           #class PhySim for physical simulators build and test
+import cls_cots_ue			#class CotsUe for Airplane mode control
+
+import sshconnection 
+import epc
+import ran
+import html
+
 
 #-----------------------------------------------------------
-# Import
+# Import Libs
 #-----------------------------------------------------------
 import sys		# arg
 import re		# reg
-import pexpect		# pexpect
+import pexpect	# pexpect
 import time		# sleep
 import os
 import subprocess
@@ -51,8 +66,9 @@ logging.basicConfig(
 )
 
 
+
 #-----------------------------------------------------------
-# Class Declaration
+# OaiCiTest Class Definition
 #-----------------------------------------------------------
 class OaiCiTest():
 	
@@ -97,12 +113,13 @@ class OaiCiTest():
 		self.UEIPAddress = ''
 		self.UEUserName = ''
 		self.UEPassword = ''
-		self.UE_instance = ''
+		self.UE_instance = 0
 		self.UESourceCodePath = ''
 		self.UELogFile = ''
 		self.Build_OAI_UE_args = ''
 		self.Initialize_OAI_UE_args = ''
 		self.clean_repository = True
+		self.air_interface=''
 		self.expectedNbOfConnectedUEs = 0
 
 	def BuildOAIUE(self):
@@ -112,10 +129,10 @@ class OaiCiTest():
 		SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
 		result = re.search('--nrUE', self.Build_OAI_UE_args)
 		if result is not None:
-			RAN.Setair_interface('nr')
+			self.air_interface='nr-uesoftmodem'
 			ue_prefix = 'NR '
 		else:
-			RAN.Setair_interface('lte')
+			self.air_interface='lte-uesoftmodem'
 			ue_prefix = ''
 		result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
 		if result is not None:
@@ -155,7 +172,7 @@ class OaiCiTest():
 						mismatch = True
 				if not mismatch:
 					SSH.close()
-					HTML.CreateHtmlTestRow(RAN.GetBuild_eNB_args(), 'OK', CONST.ALL_PROCESSES_OK)
+					HTML.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK)
 					return
 
 			SSH.command('echo ' + self.UEPassword + ' | sudo -S git clean -x -d -ff', '\$', 30)
@@ -181,7 +198,7 @@ class OaiCiTest():
 		SSH.command('ls ran_build/build', '\$', 3)
 		SSH.command('ls ran_build/build', '\$', 3)
 		buildStatus = True
-		result = re.search(RAN.Getair_interface() + '-uesoftmodem', SSH.getBefore())
+		result = re.search(self.air_interface, SSH.getBefore())
 		if result is None:
 			buildStatus = False
 		SSH.command('mkdir -p build_log_' + self.testCase_id, '\$', 5)
@@ -209,33 +226,33 @@ class OaiCiTest():
 			sys.exit(1)
 	
 	def CheckFlexranCtrlInstallation(self):
-		if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '':
+		if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '':
 			return
-		SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
+		SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
 		SSH.command('ls -ls /opt/flexran_rtc/*/rt_controller', '\$', 5)
 		result = re.search('/opt/flexran_rtc/build/rt_controller', SSH.getBefore())
 		if result is not None:
-			RAN.SetflexranCtrlInstalled(True)
+			RAN.flexranCtrlInstalled=True
 			logging.debug('Flexran Controller is installed')
 		SSH.close()
 
 	def InitializeFlexranCtrl(self):
-		if RAN.GetflexranCtrlInstalled() == False:
+		if RAN.flexranCtrlInstalled == False:
 			return
-		if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '':
+		if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '':
 			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
-		SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
+		SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
 		SSH.command('cd /opt/flexran_rtc', '\$', 5)
-		SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S rm -f log/*.log', '\$', 5)
-		SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S echo "build/rt_controller -c log_config/basic_log" > ./my-flexran-ctl.sh', '\$', 5)
-		SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S chmod 755 ./my-flexran-ctl.sh', '\$', 5)
-		SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S daemon --unsafe --name=flexran_rtc_daemon --chdir=/opt/flexran_rtc -o /opt/flexran_rtc/log/flexranctl_' + self.testCase_id + '.log ././my-flexran-ctl.sh', '\$', 5)
+		SSH.command('echo ' + EPC.Password + ' | sudo -S rm -f log/*.log', '\$', 5)
+		SSH.command('echo ' + EPC.Password + ' | sudo -S echo "build/rt_controller -c log_config/basic_log" > ./my-flexran-ctl.sh', '\$', 5)
+		SSH.command('echo ' + EPC.Password + ' | sudo -S chmod 755 ./my-flexran-ctl.sh', '\$', 5)
+		SSH.command('echo ' + EPC.Password + ' | sudo -S daemon --unsafe --name=flexran_rtc_daemon --chdir=/opt/flexran_rtc -o /opt/flexran_rtc/log/flexranctl_' + self.testCase_id + '.log ././my-flexran-ctl.sh', '\$', 5)
 		SSH.command('ps -aux | grep --color=never rt_controller', '\$', 5)
 		result = re.search('rt_controller -c ', SSH.getBefore())
 		if result is not None:
 			logging.debug('\u001B[1m Initialize FlexRan Controller Completed\u001B[0m')
-			RAN.SetflexranCtrlStarted(True)
+			RAN.flexranCtrlStarted=True
 		SSH.close()
 		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 	
@@ -306,14 +323,14 @@ class OaiCiTest():
 		if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '':
 			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
-		if RAN.Getair_interface() == 'lte':
+		if self.air_interface == 'lte-uesoftmodem':
 			result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args))
 			if result is None:
 				check_eNB = True
 				check_OAI_UE = False
 				pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE)
 				if (pStatus < 0):
-					HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', pStatus)
+					HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'KO', pStatus)
 					HTML.CreateHtmlTabFooter(False)
 					sys.exit(1)
 			UE_prefix = ''
@@ -335,7 +352,7 @@ class OaiCiTest():
 		# Initialize_OAI_UE_args usually start with -C and followed by the location in repository
 		SSH.command('source oaienv', '\$', 5)
 		SSH.command('cd cmake_targets/ran_build/build', '\$', 5)
-		if RAN.Getair_interface() == 'lte':
+		if self.air_interface == 'lte-uesoftmodem':
 			result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args))
 			# We may have to regenerate the .u* files
 			if result is None:
@@ -351,13 +368,13 @@ class OaiCiTest():
 			SSH.command('if [ -e rbconfig.raw ]; then echo ' + self.UEPassword + ' | sudo -S rm rbconfig.raw; fi', '\$', 5)
 			SSH.command('if [ -e reconfig.raw ]; then echo ' + self.UEPassword + ' | sudo -S rm reconfig.raw; fi', '\$', 5)
 			# Copy the RAW files from gNB running directory (maybe on another machine)
-			copyin_res = SSH.copyin(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath() + '/cmake_targets/rbconfig.raw', '.')
+			copyin_res = SSH.copyin(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath + '/cmake_targets/rbconfig.raw', '.')
 			if (copyin_res == 0):
 				SSH.copyout(self.UEIPAddress, self.UEUserName, self.UEPassword, './rbconfig.raw', self.UESourceCodePath + '/cmake_targets/ran_build/build')
-			copyin_res = SSH.copyin(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath() + '/cmake_targets/reconfig.raw', '.')
+			copyin_res = SSH.copyin(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath + '/cmake_targets/reconfig.raw', '.')
 			if (copyin_res == 0):
 				SSH.copyout(self.UEIPAddress, self.UEUserName, self.UEPassword, './reconfig.raw', self.UESourceCodePath + '/cmake_targets/ran_build/build')
-		SSH.command('echo "ulimit -c unlimited && ./'+ RAN.Getair_interface() +'-uesoftmodem ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
+		SSH.command('echo "ulimit -c unlimited && ./'+ self.air_interface +' ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
 		SSH.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
 		SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5)
 		self.UELogFile = 'ue_' + self.testCase_id + '.log'
@@ -370,9 +387,7 @@ class OaiCiTest():
 		while (doOutterLoop):
 			SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets/ran_build/build', '\$', 5)
 			SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5)
-			#use nohup instead of daemon
-			#SSH.command('echo ' + self.UEPassword + ' | sudo -S -E daemon --inherit --unsafe --name=ue' + str(self.UE_instance) + '_daemon --chdir=' + self.UESourceCodePath + '/cmake_targets/ran_build/build -o ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
-			SSH.command('echo $USER; nohup sudo ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh' + ' > ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ' + ' 2>&1 &', self.UEUserName, 5)
+			SSH.command('echo $USER; nohup sudo -E ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh' + ' > ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ' + ' 2>&1 &', self.UEUserName, 5)
 			time.sleep(6)
 			SSH.command('cd ../..', '\$', 5)
 			doLoop = True
@@ -388,7 +403,7 @@ class OaiCiTest():
 					doLoop = False
 					continue
 				SSH.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4)
-				if RAN.Getair_interface() == 'nr':
+				if self.air_interface == 'nr-uesoftmodem':
 					result = re.search('Starting sync detection', SSH.getBefore())
 				else:
 					result = re.search('got sync', SSH.getBefore())
@@ -413,7 +428,7 @@ class OaiCiTest():
 			# That is the case for LTE
 			# In NR case, it's a positive message that will show if synchronization occurs
 			doLoop = True
-			if RAN.Getair_interface() == 'nr':
+			if self.air_interface == 'nr-uesoftmodem':
 				loopCounter = 10
 			else:
 				# We are now checking if sync w/ eNB DOES NOT OCCUR
@@ -422,7 +437,7 @@ class OaiCiTest():
 			while (doLoop):
 				loopCounter = loopCounter - 1
 				if (loopCounter == 0):
-					if RAN.Getair_interface() == 'nr':
+					if self.air_interface == 'nr-uesoftmodem':
 						# Here we do have great chances that UE did NOT cell-sync w/ gNB
 						doLoop = False
 						fullSyncStatus = False
@@ -441,7 +456,7 @@ class OaiCiTest():
 						fullSyncStatus = True
 						continue
 				SSH.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync|Frequency"', '\$', 4)
-				if RAN.Getair_interface() == 'nr':
+				if self.air_interface == 'nr-uesoftmodem':
 					# Positive messaging -->
 					result = re.search('Measured Carrier Frequency', SSH.getBefore())
 					if result is not None:
@@ -470,12 +485,12 @@ class OaiCiTest():
 
 		if fullSyncStatus and gotSyncStatus:
 			doInterfaceCheck = False
-			if RAN.Getair_interface() == 'lte':
+			if self.air_interface == 'lte-uesoftmodem':
 				result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args))
 				if result is None:
 					doInterfaceCheck = True
 			# For the moment, only in explicit noS1 without kernel module (ie w/ tunnel interface)
-			if RAN.Getair_interface() == 'nr':
+			if self.air_interface == 'nr-uesoftmodem':
 				result = re.search('--noS1 --nokrnmod 1', str(self.Initialize_OAI_UE_args))
 				if result is not None:
 					doInterfaceCheck = True
@@ -491,7 +506,7 @@ class OaiCiTest():
 					logging.debug(SSH.getBefore())
 					logging.error('\u001B[1m oaitun_ue1 interface is either NOT mounted or NOT configured\u001B[0m')
 					tunnelInterfaceStatus = False
-				if RAN.GeteNBmbmsEnable(0):
+				if RAN.eNBmbmsEnables[0]:
 					SSH.command('ifconfig oaitun_uem1', '\$', 4)
 					result = re.search('inet addr', SSH.getBefore())
 					if result is not None:
@@ -507,7 +522,7 @@ class OaiCiTest():
 
 		SSH.close()
 		if fullSyncStatus and gotSyncStatus and tunnelInterfaceStatus:
-			HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK, 'OAI UE')
+			HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK, 'OAI UE')
 			logging.debug('\u001B[1m Initialize OAI UE Completed\u001B[0m')
 			if (self.ADBIPAddress != 'none'):
 				self.UEDevices = []
@@ -515,15 +530,15 @@ class OaiCiTest():
 				self.UEDevicesStatus = []
 				self.UEDevicesStatus.append(CONST.UE_STATUS_DETACHED)
 		else:
-			if RAN.Getair_interface() == 'lte':
-				if RAN.GeteNBmbmsEnable(0):
-					HTML.SethtmlUEFailureMsg('oaitun_ue1/oaitun_uem1 interfaces are either NOT mounted or NOT configured')
+			if self.air_interface == 'lte-uesoftmodem':
+				if RAN.eNBmbmsEnables[0]:
+					HTML.htmlUEFailureMsg='oaitun_ue1/oaitun_uem1 interfaces are either NOT mounted or NOT configured'
 				else:
-					HTML.SethtmlUEFailureMsg('oaitun_ue1 interface is either NOT mounted or NOT configured')
-				HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE')
+					HTML.htmlUEFailureMsg='oaitun_ue1 interface is either NOT mounted or NOT configured'
+				HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE')
 			else:
-				HTML.SethtmlUEFailureMsg('nr-uesoftmodem did NOT synced')
-				HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_COULD_NOT_SYNC, 'OAI UE')
+				HTML.htmlUEFailureMsg='nr-uesoftmodem did NOT synced'
+				HTML.CreateHtmlTestRow(self.air_interface + ' ' +  self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_COULD_NOT_SYNC, 'OAI UE')
 			logging.error('\033[91mInitialize OAI UE Failed! \033[0m')
 			self.AutoTerminateUEandeNB()
 
@@ -675,7 +690,7 @@ class OaiCiTest():
 			self.AutoTerminateUEandeNB()
 
 	def PingCatM(self):
-		if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '':
+		if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '':
 			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
 		check_eNB = True
@@ -688,10 +703,10 @@ class OaiCiTest():
 		try:
 			statusQueue = SimpleQueue()
 			lock = Lock()
-			SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
-			SSH.command('cd ' + EPC.GetSourceCodePath(), '\$', 5)
+			SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+			SSH.command('cd ' + EPC.SourceCodePath, '\$', 5)
 			SSH.command('cd scripts', '\$', 5)
-			if re.match('OAI', EPC.GetType(), re.IGNORECASE):
+			if re.match('OAI', EPC.Type, re.IGNORECASE):
 				logging.debug('Using the OAI EPC HSS: not implemented yet')
 				HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
 				HTML.CreateHtmlTabFooter(False)
@@ -891,7 +906,7 @@ class OaiCiTest():
 						self.UEDevicesStatus[cnt] = CONST.UE_STATUS_ATTACHED
 					cnt += 1
 				HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue)
-				result = re.search('T_stdout', str(RAN.GetInitialize_eNB_args()))
+				result = re.search('T_stdout', str(RAN.Initialize_eNB_args))
 				if result is not None:
 					logging.debug('Waiting 5 seconds to fill up record file')
 					time.sleep(5)
@@ -937,7 +952,7 @@ class OaiCiTest():
 		for job in multi_jobs:
 			job.join()
 		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
-		result = re.search('T_stdout', str(RAN.GetInitialize_eNB_args()))
+		result = re.search('T_stdout', str(RAN.Initialize_eNB_args))
 		if result is not None:
 			logging.debug('Waiting 5 seconds to fill up record file')
 			time.sleep(5)
@@ -1071,7 +1086,6 @@ class OaiCiTest():
 		SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 		if self.ADBCentralized:
 			SSH.command('adb devices', '\$', 15)
-			#self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",SSH.getBefore())
 			self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",SSH.getBefore())
 			SSH.close()
 		else:
@@ -1203,8 +1217,8 @@ class OaiCiTest():
 			i += 1
 		for job in multi_jobs:
 			job.join()
-		if RAN.GetflexranCtrlInstalled() and RAN.GetflexranCtrlStarted():
-			SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
+		if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted:
+			SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
 			SSH.command('cd /opt/flexran_rtc', '\$', 5)
 			SSH.command('curl http://localhost:9999/stats | jq \'.\' > log/check_status_' + self.testCase_id + '.log 2>&1', '\$', 5)
 			SSH.command('cat log/check_status_' + self.testCase_id + '.log | jq \'.eNB_config[0].UE\' | grep -c rnti | sed -e "s#^#Nb Connected UE = #"', '\$', 5)
@@ -1316,13 +1330,13 @@ class OaiCiTest():
 			# Launch ping on the EPC side (true for ltebox and old open-air-cn)
 			# But for OAI-Rel14-CUPS, we launch from python executor
 			launchFromEpc = True
-			if re.match('OAI-Rel14-CUPS', EPC.GetType(), re.IGNORECASE):
+			if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE):
 				launchFromEpc = False
 			ping_time = re.findall("-c (\d+)",str(self.ping_args))
 
 			if launchFromEpc:
-				SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
-				SSH.command('cd ' + EPC.GetSourceCodePath(), '\$', 5)
+				SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+				SSH.command('cd ' + EPC.SourceCodePath, '\$', 5)
 				SSH.command('cd scripts', '\$', 5)
 				ping_status = SSH.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5)
 			else:
@@ -1331,9 +1345,9 @@ class OaiCiTest():
 				logging.debug(cmd)
 				ret = subprocess.run(cmd, shell=True)
 				ping_status = ret.returncode
-				SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'ping_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts')
-				SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
-				SSH.command('cat ' + EPC.GetSourceCodePath() + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
+				SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'ping_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts')
+				SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+				SSH.command('cat ' + EPC.SourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
 			# TIMEOUT CASE
 			if ping_status < 0:
 				message = 'Ping with UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT!'
@@ -1413,7 +1427,7 @@ class OaiCiTest():
 			return
 		ping_from_eNB = re.search('oaitun_enb1', str(self.ping_args))
 		if ping_from_eNB is not None:
-			if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '':
+			if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '':
 				HELP.GenericHelp(CONST.Version)
 				sys.exit('Insufficient Parameter')
 		else:
@@ -1422,8 +1436,8 @@ class OaiCiTest():
 				sys.exit('Insufficient Parameter')
 		try:
 			if ping_from_eNB is not None:
-				SSH.open(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword())
-				SSH.command('cd ' + RAN.GeteNBSourceCodePath() + '/cmake_targets/', '\$', 5)
+				SSH.open(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword)
+				SSH.command('cd ' + RAN.eNBSourceCodePath + '/cmake_targets/', '\$', 5)
 			else:
 				SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
 				SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets/', '\$', 5)
@@ -1487,20 +1501,20 @@ class OaiCiTest():
 
 			# copying on the EPC server for logCollection
 			if ping_from_eNB is not None:
-				copyin_res = SSH.copyin(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath() + '/cmake_targets/ping_' + self.testCase_id + '.log', '.')
+				copyin_res = SSH.copyin(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.')
 			else:
 				copyin_res = SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.')
 			if (copyin_res == 0):
-				SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'ping_' + self.testCase_id + '.log', EPC.GetSourceCodePath() + '/scripts')
+				SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'ping_' + self.testCase_id + '.log', EPC.SourceCodePath + '/scripts')
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
 	def Ping(self):
-		result = re.search('noS1', str(RAN.GetInitialize_eNB_args()))
+		result = re.search('noS1', str(RAN.Initialize_eNB_args))
 		if result is not None:
 			self.PingNoS1()
 			return
-		if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '':
+		if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '':
 			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
 		check_eNB = True
@@ -1586,7 +1600,7 @@ class OaiCiTest():
 		return result
 
 	def Iperf_analyzeV2TCPOutput(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options):
-		SSH.command('awk -f /tmp/tcp_iperf_stats.awk /tmp/CI-eNB/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
+		SSH.command('awk -f /tmp/tcp_iperf_stats.awk ' + EPC.SourceCodePath + '/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
 		result = re.search('Avg Bitrate : (?P<average>[0-9\.]+ Mbits\/sec) Max Bitrate : (?P<maximum>[0-9\.]+ Mbits\/sec) Min Bitrate : (?P<minimum>[0-9\.]+ Mbits\/sec)', SSH.getBefore())
 		if result is not None:
 			avgbitrate = result.group('average')
@@ -1844,7 +1858,7 @@ class OaiCiTest():
 		# Launch iperf server on EPC side (true for ltebox and old open-air-cn0
 		# But for OAI-Rel14-CUPS, we launch from python executor and we are using its IP address as iperf client address
 		launchFromEpc = True
-		if re.match('OAI-Rel14-CUPS', EPC.GetType(), re.IGNORECASE):
+		if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE):
 			launchFromEpc = False
 			cmd = 'hostname -I'
 			ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8')
@@ -1852,13 +1866,13 @@ class OaiCiTest():
 				EPC_Iperf_UE_IPAddress = ret.stdout.strip()
 		port = 5001 + idx
 		if launchFromEpc:
-			SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
-			SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5)
+			SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+			SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5)
 			SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
 			if udpIperf:
-				SSH.command('echo $USER; nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', EPC.GetUserName(), 5)
+				SSH.command('echo $USER; nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', EPC.UserName, 5)
 			else:
-				SSH.command('echo $USER; nohup iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', EPC.GetUserName(), 5)
+				SSH.command('echo $USER; nohup iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', EPC.UserName, 5)
 			SSH.close()
 		else:
 			if self.ueIperfVersion == self.dummyIperfVersion:
@@ -1881,7 +1895,7 @@ class OaiCiTest():
 			SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5)
 		else:
 			SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
-			SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5)
+			SSH.command('cd ' + EPC.SourceCodePath+ '/scripts', '\$', 5)
 		iperf_time = self.Iperf_ComputeTime()
 		time.sleep(0.5)
 
@@ -1915,27 +1929,27 @@ class OaiCiTest():
 
 		# Kill iperf server on EPC side
 		if launchFromEpc:
-			SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
-			SSH.command('killall --signal SIGKILL iperf', EPC.GetUserName(), 5)
+			SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+			SSH.command('killall --signal SIGKILL iperf', EPC.UserName, 5)
 			SSH.close()
 		else:
 			cmd = 'killall --signal SIGKILL iperf'
 			logging.debug(cmd)
 			subprocess.run(cmd, shell=True)
 			time.sleep(1)
-			SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts')
+			SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts')
 		# in case of failure, retrieve server log
 		if (clientStatus == -1) or (clientStatus == -2):
 			if launchFromEpc:
 				time.sleep(1)
 				if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')):
 					os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log')
-				SSH.copyin(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), EPC.GetSourceCodePath() + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
+				SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath+ '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
 			self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options)
 		# in case of OAI-UE 
 		if (device_id == 'OAI-UE'):
 			SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_' + self.testCase_id + '_' + device_id + '.log', '.')
-			SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts')
+			SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts')
 
 	def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue):
 		try:
@@ -1949,8 +1963,8 @@ class OaiCiTest():
 			if (device_id != 'OAI-UE'):
 				SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 				# if by chance ADB server and EPC are on the same remote host, at least log collection will take care of it
-				SSH.command('if [ ! -d ' + EPC.GetSourceCodePath() + '/scripts ]; then mkdir -p ' + EPC.GetSourceCodePath() + '/scripts ; fi', '\$', 5)
-				SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5)
+				SSH.command('if [ ! -d ' + EPC.SourceCodePath + '/scripts ]; then mkdir -p ' + EPC.SourceCodePath + '/scripts ; fi', '\$', 5)
+				SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5)
 				# Checking if iperf / iperf3 are installed
 				if self.ADBCentralized:
 					SSH.command('adb -s ' + device_id + ' shell "ls /data/local/tmp"', '\$', 5)
@@ -2009,7 +2023,7 @@ class OaiCiTest():
 					SSH.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -u -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5)
 			else:
 				SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
-				SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5)
+				SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5)
 				if self.ADBCentralized:
 					if (useIperf3):
 						SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/iperf3 -s &', '\$', 5)
@@ -2031,11 +2045,11 @@ class OaiCiTest():
 			# Launch the IPERF client on the EPC side for DL (true for ltebox and old open-air-cn
 			# But for OAI-Rel14-CUPS, we launch from python executor
 			launchFromEpc = True
-			if re.match('OAI-Rel14-CUPS', EPC.GetType(), re.IGNORECASE):
+			if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE):
 				launchFromEpc = False
 			if launchFromEpc:
-				SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
-				SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5)
+				SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+				SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5)
 			iperf_time = self.Iperf_ComputeTime()
 			time.sleep(0.5)
 
@@ -2070,9 +2084,9 @@ class OaiCiTest():
 					logging.debug(cmd)
 					ret = subprocess.run(cmd, shell=True)
 					iperf_status = ret.returncode
-					SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts')
-					SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
-					SSH.command('cat ' + EPC.GetSourceCodePath() + '/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
+					SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts')
+					SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+					SSH.command('cat ' + EPC.SourceCodePath + '/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
 				if iperf_status < 0:
 					if launchFromEpc:
 						SSH.close()
@@ -2109,7 +2123,7 @@ class OaiCiTest():
 				if (device_id == 'OAI-UE'):
 					SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
 				else:
-					SSH.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, EPC.GetSourceCodePath() + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
+					SSH.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, EPC.SourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
 				# fromdos has to be called on the python executor not on ADB server
 				cmd = 'fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log'
 				subprocess.run(cmd, shell=True)
@@ -2119,15 +2133,15 @@ class OaiCiTest():
 			if (device_id == 'OAI-UE'):
 				if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')):
 					if not launchFromEpc:
-						SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts')
+						SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts')
 				else:
 					SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
-					SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts')
+					SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts')
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
 	def IperfNoS1(self):
-		if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '':
+		if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '':
 			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
 		check_eNB = True
@@ -2139,9 +2153,9 @@ class OaiCiTest():
 			return
 		server_on_enb = re.search('-R', str(self.iperf_args))
 		if server_on_enb is not None:
-			iServerIPAddr = RAN.GeteNBIPAddress()
-			iServerUser = RAN.GeteNBUserName()
-			iServerPasswd = RAN.GeteNBPassword()
+			iServerIPAddr = RAN.eNBIPAddress
+			iServerUser = RAN.eNBUserName
+			iServerPasswd = RAN.eNBPassword
 			iClientIPAddr = self.UEIPAddress
 			iClientUser = self.UEUserName
 			iClientPasswd = self.UEPassword
@@ -2149,9 +2163,9 @@ class OaiCiTest():
 			iServerIPAddr = self.UEIPAddress
 			iServerUser = self.UEUserName
 			iServerPasswd = self.UEPassword
-			iClientIPAddr = RAN.GeteNBIPAddress()
-			iClientUser = RAN.GeteNBUserName()
-			iClientPasswd = RAN.GeteNBPassword()
+			iClientIPAddr = RAN.eNBIPAddress
+			iClientUser = RAN.eNBUserName
+			iClientPasswd = RAN.eNBPassword
 		if self.iperf_options != 'sink':
 			# Starting the iperf server
 			SSH.open(iServerIPAddr, iServerUser, iServerPasswd)
@@ -2206,10 +2220,10 @@ class OaiCiTest():
 		if (clientStatus == -1):
 			copyin_res = SSH.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log')
 			if (copyin_res == 0):
-				SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_server_' + self.testCase_id + '_OAI-UE.log', EPC.GetSourceCodePath() + '/scripts')
+				SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_OAI-UE.log', EPC.SourceCodePath + '/scripts')
 		copyin_res = SSH.copyin(iClientIPAddr, iClientUser, iClientPasswd, '/tmp/tmp_iperf_' + self.testCase_id + '.log', 'iperf_' + self.testCase_id + '_OAI-UE.log')
 		if (copyin_res == 0):
-			SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_' + self.testCase_id + '_OAI-UE.log', EPC.GetSourceCodePath() + '/scripts')
+			SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_OAI-UE.log', EPC.SourceCodePath + '/scripts')
 		iperf_noperf = False
 		if status_queue.empty():
 			iperf_status = False
@@ -2236,11 +2250,11 @@ class OaiCiTest():
 			self.AutoTerminateUEandeNB()
 
 	def Iperf(self):
-		result = re.search('noS1', str(RAN.GetInitialize_eNB_args()))
+		result = re.search('noS1', str(RAN.Initialize_eNB_args))
 		if result is not None:
 			self.IperfNoS1()
 			return
-		if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
+		if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
 			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
 		check_eNB = True
@@ -2317,7 +2331,7 @@ class OaiCiTest():
 		status_queue = SimpleQueue()
 		# in noS1 config, no need to check status from EPC
 		# in gNB also currently no need to check
-		result = re.search('noS1|band78', str(RAN.GetInitialize_eNB_args()))
+		result = re.search('noS1|band78', str(RAN.Initialize_eNB_args))
 		if result is None:
 			p = Process(target = EPC.CheckHSSProcess, args = (status_queue,))
 			p.daemon = True
@@ -2356,14 +2370,14 @@ class OaiCiTest():
 				if (status < 0):
 					result = status
 			if result == CONST.ENB_PROCESS_FAILED:
-				fileCheck = re.search('enb_', str(RAN.GeteNBLogFile(0)))
+				fileCheck = re.search('enb_', str(RAN.eNBLogFiles[0]))
 				if fileCheck is not None:
-					SSH.copyin(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath() + '/cmake_targets/' + RAN.GeteNBLogFile(0), '.')
-					logStatus = RAN.AnalyzeLogFile_eNB(RAN.GeteNBLogFile[0])
+					SSH.copyin(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath + '/cmake_targets/' + RAN.eNBLogFiles[0], '.')
+					logStatus = RAN.AnalyzeLogFile_eNB(RAN.eNBLogFiles[0])
 					if logStatus < 0:
 						result = logStatus
-					RAN.SeteNBLogFile('', 0)
-				if RAN.GetflexranCtrlInstalled() and RAN.GetflexranCtrlStarted():
+					RAN.eNBLogFiles[0]=''
+				if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted:
 					self.TerminateFlexranCtrl()
 			return result
 
@@ -2398,8 +2412,8 @@ class OaiCiTest():
 	def CheckOAIUEProcess(self, status_queue):
 		try:
 			SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
-			SSH.command('stdbuf -o0 ps -aux | grep --color=never ' + RAN.Getair_interface() + '-uesoftmodem | grep -v grep', '\$', 5)
-			result = re.search(RAN.Getair_interface() + '-uesoftmodem', SSH.getBefore())
+			SSH.command('stdbuf -o0 ps -aux | grep --color=never ' + self.air_interface + ' | grep -v grep', '\$', 5)
+			result = re.search(self.air_interface, SSH.getBefore())
 			if result is None:
 				logging.debug('\u001B[1;37;41m OAI UE Process Not Found! \u001B[0m')
 				status_queue.put(CONST.OAI_UE_PROCESS_FAILED)
@@ -2436,7 +2450,7 @@ class OaiCiTest():
 		nrFoundDCI = 0
 		nrCRCOK = 0
 		mbms_messages = 0
-		HTML.SethtmlUEFailureMsg('')
+		HTML.htmlUEFailureMsg=''
 		global_status = CONST.ALL_PROCESSES_OK
 		for line in ue_log_file.readlines():
 			result = re.search('nr_synchro_time', str(line))
@@ -2498,7 +2512,7 @@ class OaiCiTest():
 			result = re.search('No cell synchronization found, abandoning', str(line))
 			if result is not None:
 				no_cell_sync_found = True
-			if RAN.GeteNBmbmsEnable(0):
+			if RAN.eNBmbmsEnables[0]:
 				result = re.search('TRIED TO PUSH MBMS DATA', str(line))
 				if result is not None:
 					mbms_messages += 1
@@ -2506,22 +2520,22 @@ class OaiCiTest():
 			if result is not None and (not mib_found):
 				try:
 					mibMsg = "MIB Information: " + result.group(1) + ', ' + result.group(2)
-					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n')
+					HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n'
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 					mibMsg = "    nidcell = " + result.group('nidcell')
-					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg)
+					HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 					mibMsg = "    n_rb_dl = " + result.group('n_rb_dl')
-					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n')
+					HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n'
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 					mibMsg = "    phich_duration = " + result.group('phich_duration')
-					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg)
+					HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 					mibMsg = "    phich_resource = " + result.group('phich_resource')
-					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n')
+					HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n'
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 					mibMsg = "    tx_ant = " + result.group('tx_ant')
-					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n')
+					HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n'
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 					mib_found = True
 				except Exception as e:
@@ -2530,7 +2544,7 @@ class OaiCiTest():
 			if result is not None and (not frequency_found):
 				try:
 					mibMsg = "Measured Carrier Frequency = " + result.group('measured_carrier_frequency') + ' Hz'
-					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n')
+					HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n'
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 					frequency_found = True
 				except Exception as e:
@@ -2539,7 +2553,7 @@ class OaiCiTest():
 			if result is not None and (not plmn_found):
 				try:
 					mibMsg = 'PLMN MCC = ' + result.group('mcc') + ' MNC = ' + result.group('mnc')
-					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n')
+					HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n'
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 					plmn_found = True
 				except Exception as e:
@@ -2548,7 +2562,7 @@ class OaiCiTest():
 			if result is not None:
 				try:
 					mibMsg = "The operator is: " + result.group('operator')
-					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n')
+					HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n'
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 				except Exception as e:
 					logging.error('\033[91m' + "Operator name not found" + '\033[0m')
@@ -2556,7 +2570,7 @@ class OaiCiTest():
 			if result is not None:
 				try:
 					mibMsg = "SIB5 InterFreqCarrierFreq element " + result.group(1) + '/' + result.group(2)
-					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + ' -> ')
+					HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + ' -> '
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 				except Exception as e:
 					logging.error('\033[91m' + "SIB5 InterFreqCarrierFreq element not found" + '\033[0m')
@@ -2566,7 +2580,7 @@ class OaiCiTest():
 					freq = result.group('carrier_frequency')
 					new_freq = re.sub('/[0-9]+','',freq)
 					float_freq = float(new_freq) / 1000000
-					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + 'DL Freq: ' + ('%.1f' % float_freq) + ' MHz')
+					HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'DL Freq: ' + ('%.1f' % float_freq) + ' MHz'
 					logging.debug('\033[94m' + "    DL Carrier Frequency is: " + str(freq) + '\033[0m')
 				except Exception as e:
 					logging.error('\033[91m' + "    DL Carrier Frequency not found" + '\033[0m')
@@ -2574,7 +2588,7 @@ class OaiCiTest():
 			if result is not None:
 				try:
 					prb = result.group('allowed_bandwidth')
-					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + ' -- PRB: ' + prb + '\n')
+					HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + ' -- PRB: ' + prb + '\n'
 					logging.debug('\033[94m' + "    AllowedMeasBandwidth: " + prb + '\033[0m')
 				except Exception as e:
 					logging.error('\033[91m' + "    AllowedMeasBandwidth not found" + '\033[0m')
@@ -2582,57 +2596,57 @@ class OaiCiTest():
 		if rrcConnectionRecfgComplete > 0:
 			statMsg = 'UE connected to eNB (' + str(rrcConnectionRecfgComplete) + ' RRCConnectionReconfigurationComplete message(s) generated)'
 			logging.debug('\033[94m' + statMsg + '\033[0m')
-			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
+			HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
 		if nrUEFlag:
 			if nrDecodeMib > 0:
 				statMsg = 'UE showed ' + str(nrDecodeMib) + ' MIB decode message(s)'
 				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-				HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
+				HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
 			if nrFoundDCI > 0:
 				statMsg = 'UE showed ' + str(nrFoundDCI) + ' DCI found message(s)'
 				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-				HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
+				HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
 			if nrCRCOK > 0:
 				statMsg = 'UE showed ' + str(nrCRCOK) + ' PDSCH decoding message(s)'
 				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-				HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
+				HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
 			if not frequency_found:
 				statMsg = 'NR-UE could NOT synch!'
 				logging.error('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-				HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
+				HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
 		if uciStatMsgCount > 0:
 			statMsg = 'UE showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)'
 			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
+			HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
 		if pdcpDataReqFailedCount > 0:
 			statMsg = 'UE showed ' + str(pdcpDataReqFailedCount) + ' "PDCP data request failed" message(s)'
 			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
+			HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
 		if badDciCount > 0:
 			statMsg = 'UE showed ' + str(badDciCount) + ' "bad DCI 1(A)" message(s)'
 			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
+			HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
 		if f1aRetransmissionCount > 0:
 			statMsg = 'UE showed ' + str(f1aRetransmissionCount) + ' "Format1A Retransmission but TBS are different" message(s)'
 			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
+			HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
 		if fatalErrorCount > 0:
 			statMsg = 'UE showed ' + str(fatalErrorCount) + ' "FATAL ERROR:" message(s)'
 			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
+			HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
 		if macBsrTimerExpiredCount > 0:
 			statMsg = 'UE showed ' + str(fatalErrorCount) + ' "MAC BSR Triggered ReTxBSR Timer expiry" message(s)'
 			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
-		if RAN.GeteNBmbmsEnable(0):
+			HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
+		if RAN.eNBmbmsEnables[0]:
 			if mbms_messages > 0:
 				statMsg = 'UE showed ' + str(mbms_messages) + ' "TRIED TO PUSH MBMS DATA" message(s)'
 				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
 			else:
 				statMsg = 'UE did NOT SHOW "TRIED TO PUSH MBMS DATA" message(s)'
 				logging.debug('\u001B[1;30;41m ' + statMsg + ' \u001B[0m')
-				global_status = OAI_UE_PROCESS_NO_MBMS_MSGS
-			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
+				global_status = CONST.OAI_UE_PROCESS_NO_MBMS_MSGS
+			HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
 		if foundSegFault:
 			logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m')
 			if not nrUEFlag:
@@ -2642,7 +2656,7 @@ class OaiCiTest():
 					global_status = CONST.OAI_UE_PROCESS_SEG_FAULT
 		if foundAssertion:
 			logging.debug('\u001B[1;30;43m UE showed an assertion! \u001B[0m')
-			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + 'UE showed an assertion!\n')
+			HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'UE showed an assertion!\n'
 			if not nrUEFlag:
 				if not mib_found or not frequency_found:
 					global_status = CONST.OAI_UE_PROCESS_ASSERTION
@@ -2651,31 +2665,31 @@ class OaiCiTest():
 					global_status = CONST.OAI_UE_PROCESS_ASSERTION
 		if foundRealTimeIssue:
 			logging.debug('\u001B[1;37;41m UE faced real time issues! \u001B[0m')
-			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + 'UE faced real time issues!\n')
+			HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'UE faced real time issues!\n'
 		if nrUEFlag:
 			if not frequency_found:
 				global_status = CONST.OAI_UE_PROCESS_COULD_NOT_SYNC
 		else:
 			if no_cell_sync_found and not mib_found:
 				logging.debug('\u001B[1;37;41m UE could not synchronize ! \u001B[0m')
-				HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + 'UE could not synchronize!\n')
+				HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'UE could not synchronize!\n'
 				global_status = CONST.OAI_UE_PROCESS_COULD_NOT_SYNC
 		return global_status
 
 
 	def TerminateFlexranCtrl(self):
-		if RAN.GetflexranCtrlInstalled() == False or RAN.GetflexranCtrlStarted() == False:
+		if RAN.flexranCtrlInstalled == False or RAN.flexranCtrlStarted == False:
 			return
-		if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '':
+		if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '':
 			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
-		SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
-		SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S daemon --name=flexran_rtc_daemon --stop', '\$', 5)
+		SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+		SSH.command('echo ' + EPC.Password + ' | sudo -S daemon --name=flexran_rtc_daemon --stop', '\$', 5)
 		time.sleep(1)
-		SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S killall --signal SIGKILL rt_controller', '\$', 5)
+		SSH.command('echo ' + EPC.Password + ' | sudo -S killall --signal SIGKILL rt_controller', '\$', 5)
 		time.sleep(1)
 		SSH.close()
-		RAN.SetflexranCtrlStarted(False)
+		RAN.flexranCtrlStarted=False
 		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 
 	def TerminateUE_common(self, device_id, idx):
@@ -2741,7 +2755,7 @@ class OaiCiTest():
 			copyin_res = SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.')
 			if (copyin_res == -1):
 				logging.debug('\u001B[1;37;41m Could not copy UE logfile to analyze it! \u001B[0m')
-				HTML.SethtmlUEFailureMsg('Could not copy UE logfile to analyze it!')
+				HTML.htmlUEFailureMsg='Could not copy UE logfile to analyze it!'
 				HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE, 'UE')
 				self.UELogFile = ''
 				return
@@ -2754,9 +2768,9 @@ class OaiCiTest():
 				ueAction = 'Connection'
 			if (logStatus < 0):
 				logging.debug('\u001B[1m' + ueAction + ' Failed \u001B[0m')
-				HTML.SethtmlUEFailureMsg('<b>' + ueAction + ' Failed</b>\n' + HTML.GethtmlUEFailureMsg())
+				HTML.htmlUEFailureMsg='<b>' + ueAction + ' Failed</b>\n' + HTML.htmlUEFailureMsg
 				HTML.CreateHtmlTestRow('N/A', 'KO', logStatus, 'UE')
-				if RAN.Getair_interface() == 'lte':
+				if self.air_interface == 'lte-uesoftmodem':
 					# In case of sniffing on commercial eNBs we have random results
 					# Not an error then
 					if (logStatus != CONST.OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'):
@@ -2768,7 +2782,7 @@ class OaiCiTest():
 						self.AutoTerminateUEandeNB()
 			else:
 				logging.debug('\u001B[1m' + ueAction + ' Completed \u001B[0m')
-				HTML.SethtmlUEFailureMsg('<b>' + ueAction + ' Completed</b>\n' + HTML.GethtmlUEFailureMsg())
+				HTML.htmlUEFailureMsg='<b>' + ueAction + ' Completed</b>\n' + HTML.htmlUEFailureMsg
 				HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 			self.UELogFile = ''
 		else:
@@ -2777,41 +2791,41 @@ class OaiCiTest():
 	def AutoTerminateUEandeNB(self):
 		if (self.ADBIPAddress != 'none'):
 			self.testCase_id = 'AUTO-KILL-UE'
-			HTML.SettestCase_id(self.testCase_id)
+			HTML.testCase_id=self.testCase_id
 			self.desc = 'Automatic Termination of UE'
-			HTML.Setdesc('Automatic Termination of UE')
+			HTML.desc='Automatic Termination of UE'
 			self.ShowTestID()
 			self.TerminateUE()
 		if (self.Initialize_OAI_UE_args != ''):
 			self.testCase_id = 'AUTO-KILL-OAI-UE'
-			HTML.SettestCase_id(self.testCase_id)
+			HTML.testCase_id=self.testCase_id
 			self.desc = 'Automatic Termination of OAI-UE'
-			HTML.Setdesc('Automatic Termination of OAI-UE')
+			HTML.desc='Automatic Termination of OAI-UE'
 			self.ShowTestID()
 			self.TerminateOAIUE()
-		if (RAN.GetInitialize_eNB_args() != ''):
+		if (RAN.Initialize_eNB_args != ''):
 			self.testCase_id = 'AUTO-KILL-eNB'
-			HTML.SettestCase_id(self.testCase_id)
+			HTML.testCase_id=self.testCase_id
 			self.desc = 'Automatic Termination of eNB'
-			HTML.Setdesc('Automatic Termination of eNB')
+			HTML.desc='Automatic Termination of eNB'
 			self.ShowTestID()
-			RAN.SeteNB_instance('0')
+			RAN.eNB_instance=0
 			RAN.TerminateeNB()
-		if RAN.GetflexranCtrlInstalled() and RAN.GetflexranCtrlStarted():
+		if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted:
 			self.testCase_id = 'AUTO-KILL-flexran-ctl'
-			HTML.SettestCase_id(self.testCase_id)
+			HTML.testCase_id=self.testCase_id
 			self.desc = 'Automatic Termination of FlexRan CTL'
-			HTML.Setdesc('Automatic Termination of FlexRan CTL')
+			HTML.desc='Automatic Termination of FlexRan CTL'
 			self.ShowTestID()
 			self.TerminateFlexranCtrl()
-		RAN.SetprematureExit(True)
+		RAN.prematureExit=True
 
 	def IdleSleep(self):
 		time.sleep(self.idle_sleep_time)
 		HTML.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', CONST.ALL_PROCESSES_OK)
 
 	def X2_Status(self, idx, fileName):
-		cmd = "curl --silent http://" + EPC.GetIPAddress() + ":9999/stats | jq '.' > " + fileName
+		cmd = "curl --silent http://" + EPC.IPAddress + ":9999/stats | jq '.' > " + fileName
 		message = cmd + '\n'
 		logging.debug(cmd)
 		subprocess.run(cmd, shell=True)
@@ -2860,7 +2874,7 @@ class OaiCiTest():
 		logging.debug(msg)
 		fullMessage += msg + '\n'
 		if self.x2_ho_options == 'network':
-			if RAN.GetflexranCtrlInstalled() and RAN.GetflexranCtrlStarted():
+			if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted:
 				self.x2ENBBsIds = []
 				self.x2ENBConnectedUEs = []
 				self.x2ENBBsIds.append([])
@@ -2875,7 +2889,7 @@ class OaiCiTest():
 				eNB_cnt = self.x2NbENBs
 				cnt = 0
 				while cnt < eNB_cnt:
-					cmd = "curl -XPOST http://" + EPC.GetIPAddress() + ":9999/rrc/x2_ho_net_control/enb/" + str(self.x2ENBBsIds[0][cnt]) + "/1"
+					cmd = "curl -XPOST http://" + EPC.IPAddress + ":9999/rrc/x2_ho_net_control/enb/" + str(self.x2ENBBsIds[0][cnt]) + "/1"
 					logging.debug(cmd)
 					fullMessage += cmd + '\n'
 					subprocess.run(cmd, shell=True)
@@ -2889,7 +2903,7 @@ class OaiCiTest():
 				while cnt < eNB_cnt:
 					ueIdx = 0
 					while ueIdx < len(self.x2ENBConnectedUEs[0][cnt]):
-						cmd = "curl -XPOST http://" + EPC.GetIPAddress() + ":9999/rrc/ho/senb/" + str(self.x2ENBBsIds[0][cnt]) + "/ue/" + str(self.x2ENBConnectedUEs[0][cnt][ueIdx]) + "/tenb/" + str(self.x2ENBBsIds[0][eNB_cnt - cnt - 1])
+						cmd = "curl -XPOST http://" + EPC.IPAddress() + ":9999/rrc/ho/senb/" + str(self.x2ENBBsIds[0][cnt]) + "/ue/" + str(self.x2ENBConnectedUEs[0][cnt][ueIdx]) + "/tenb/" + str(self.x2ENBBsIds[0][eNB_cnt - cnt - 1])
 						logging.debug(cmd)
 						fullMessage += cmd + '\n'
 						subprocess.run(cmd, shell=True)
@@ -2921,11 +2935,11 @@ class OaiCiTest():
 				HTML.CreateHtmlTestRow('Cannot perform requested X2 Handover', 'KO', CONST.ALL_PROCESSES_OK)
 
 	def LogCollectBuild(self):
-		if (RAN.GeteNBIPAddress() != '' and RAN.GeteNBUserName() != '' and RAN.GeteNBPassword() != ''):
-			IPAddress = RAN.GeteNBIPAddress()
-			UserName = RAN.GeteNBUserName()
-			Password = RAN.GeteNBPassword()
-			SourceCodePath = RAN.GeteNBSourceCodePath()
+		if (RAN.eNBIPAddress != '' and RAN.eNBUserName != '' and RAN.eNBPassword != ''):
+			IPAddress = RAN.eNBIPAddress
+			UserName = RAN.eNBUserName
+			Password = RAN.eNBPassword
+			SourceCodePath = RAN.eNBSourceCodePath
 		elif (self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != ''):
 			IPAddress = self.UEIPAddress
 			UserName = self.UEUserName
@@ -2940,8 +2954,8 @@ class OaiCiTest():
 		SSH.command('zip build.log.zip build_log_*/*', '\$', 60)
 		SSH.close()
 	def LogCollectPing(self):
-		SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
-		SSH.command('cd ' + EPC.GetSourceCodePath(), '\$', 5)
+		SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+		SSH.command('cd ' + EPC.SourceCodePath, '\$', 5)
 		SSH.command('cd scripts', '\$', 5)
 		SSH.command('rm -f ping.log.zip', '\$', 5)
 		SSH.command('zip ping.log.zip ping*.log', '\$', 60)
@@ -2949,8 +2963,8 @@ class OaiCiTest():
 		SSH.close()
 
 	def LogCollectIperf(self):
-		SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
-		SSH.command('cd ' + EPC.GetSourceCodePath(), '\$', 5)
+		SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+		SSH.command('cd ' + EPC.SourceCodePath, '\$', 5)
 		SSH.command('cd scripts', '\$', 5)
 		SSH.command('rm -f iperf.log.zip', '\$', 5)
 		SSH.command('zip iperf.log.zip iperf*.log', '\$', 60)
@@ -2967,20 +2981,20 @@ class OaiCiTest():
 		SSH.close()
 
 	def RetrieveSystemVersion(self, machine):
-		if RAN.GeteNBIPAddress() == 'none' or self.UEIPAddress == 'none':
-			HTML.SetOsVersion('Ubuntu 16.04.5 LTS', 0)
-			HTML.SetKernelVersion('4.15.0-45-generic', 0)
-			HTML.SetUhdVersion('3.13.0.1-0', 0)
-			HTML.SetUsrpBoard('B210', 0)
-			HTML.SetCpuNb('4', 0)
-			HTML.SetCpuModel('Intel(R) Core(TM) i5-6200U', 0)
-			HTML.SetCpuMHz('2399.996 MHz', 0)
+		if RAN.eNBIPAddress == 'none' or self.UEIPAddress == 'none':
+			HTML.OsVersion[0]='Ubuntu 16.04.5 LTS'
+			HTML.KernelVersion[0]='4.15.0-45-generic'
+			HTML.UhdVersion[0]='3.13.0.1-0'
+			HTML.UsrpBoard[0]='B210'
+			HTML.CpuNb[0]='4'
+			HTML.CpuModel[0]='Intel(R) Core(TM) i5-6200U'
+			HTML.CpuMHz[0]='2399.996 MHz'
 			return 0
 		if machine == 'eNB':
-			if RAN.GeteNBIPAddress() != '' and RAN.GeteNBUserName() != '' and RAN.GeteNBPassword() != '':
-				IPAddress = RAN.GeteNBIPAddress()
-				UserName = RAN.GeteNBUserName()
-				Password = RAN.GeteNBPassword()
+			if RAN.eNBIPAddress != '' and RAN.eNBUserName != '' and RAN.eNBPassword != '':
+				IPAddress = RAN.eNBIPAddress
+				UserName = RAN.eNBUserName
+				Password = RAN.eNBPassword
 				idx = 0
 			else:
 				return -1
@@ -2999,7 +3013,7 @@ class OaiCiTest():
 		if result is not None:
 			OsVersion = result.group('os_type')
 			logging.debug('OS is: ' + OsVersion)
-			HTML.SetOsVersion(OsVersion, idx)
+			HTML.OsVersion[idx]=OsVersion
 		else:
 			SSH.command('hostnamectl', '\$', 5)
 			result = re.search('Operating System: (?P<os_type>[a-zA-Z0-9\-\_\.\ ]+)', SSH.getBefore())
@@ -3011,26 +3025,26 @@ class OaiCiTest():
 					if result is not None:
 						OsVersion = OsVersion.replace('7 ', result.group('os_version'))
 				logging.debug('OS is: ' + OsVersion)
-				HTML.SetOsVersion(OsVersion, idx)
+				HTML.OsVersion[idx]=OsVersion
 		SSH.command('uname -r', '\$', 5)
 		result = re.search('uname -r\\\\r\\\\n(?P<kernel_version>[a-zA-Z0-9\-\_\.]+)', SSH.getBefore())
 		if result is not None:
 			KernelVersion = result.group('kernel_version')
 			logging.debug('Kernel Version is: ' + KernelVersion)
-			HTML.SetKernelVersion(KernelVersion, idx)
+			HTML.KernelVersion[idx]=KernelVersion
 		SSH.command('dpkg --list | egrep --color=never libuhd003', '\$', 5)
 		result = re.search('libuhd003:amd64 *(?P<uhd_version>[0-9\.]+)', SSH.getBefore())
 		if result is not None:
 			UhdVersion = result.group('uhd_version')
 			logging.debug('UHD Version is: ' + UhdVersion)
-			HTML.SetUhdVersion(UhdVersion, idx)
+			HTML.UhdVersion[idx]=UhdVersion
 		else:
 			SSH.command('uhd_config_info --version', '\$', 5)
 			result = re.search('UHD (?P<uhd_version>[a-zA-Z0-9\.\-]+)', SSH.getBefore())
 			if result is not None:
 				UhdVersion = result.group('uhd_version')
 				logging.debug('UHD Version is: ' + UhdVersion)
-				HTML.SetUhdVersion(UhdVersion, idx)
+				HTML.UhdVersion[idx]=UhdVersion
 		SSH.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 60)
 		usrp_boards = re.findall('product: ([0-9A-Za-z]+)\\\\r\\\\n', SSH.getBefore())
 		count = 0
@@ -3042,99 +3056,132 @@ class OaiCiTest():
 			count += 1
 		if count > 0:
 			logging.debug('USRP Board(s) : ' + UsrpBoard)
-			HTML.SetUsrpBoard(UsrpBoard, idx)
+			HTML.UsrpBoard[idx]=UsrpBoard
 		SSH.command('lscpu', '\$', 5)
 		result = re.search('CPU\(s\): *(?P<nb_cpus>[0-9]+).*Model name: *(?P<model>[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P<cpu_mhz>[0-9\.]+)', SSH.getBefore())
 		if result is not None:
 			CpuNb = result.group('nb_cpus')
 			logging.debug('nb_cpus: ' + CpuNb)
-			HTML.SetCpuNb(CpuNb, idx)
+			HTML.CpuNb[idx]=CpuNb
 			CpuModel = result.group('model')
 			logging.debug('model: ' + CpuModel)
-			HTML.SetCpuModel(CpuModel, idx)
+			HTML.CpuModel[idx]=CpuModel
 			CpuMHz = result.group('cpu_mhz') + ' MHz'
 			logging.debug('cpu_mhz: ' + CpuMHz)
-			HTML.SetCpuMHz(CpuMHz, idx)
+			HTML.CpuMHz[idx]=CpuMHz
 		SSH.close()
 
-#-----------------------------------------------------------
-# ShowTestID()
-#-----------------------------------------------------------
 	def ShowTestID(self):
 		logging.debug('\u001B[1m----------------------------------------\u001B[0m')
 		logging.debug('\u001B[1mTest ID:' + self.testCase_id + '\u001B[0m')
 		logging.debug('\u001B[1m' + self.desc + '\u001B[0m')
 		logging.debug('\u001B[1m----------------------------------------\u001B[0m')
 
-def CheckClassValidity(action,id):
-	if action!='Build_PhySim' and action!='Run_PhySim' and  action != 'Build_eNB' and action != 'WaitEndBuild_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep' and action != 'Perform_X2_Handover':
-		logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action)
-		return False
-	return True
+
+
+#-----------------------------------------------------------
+# General Functions
+#-----------------------------------------------------------
+
+
+
+def CheckClassValidity(xml_class_list,action,id):
+	if action not in xml_class_list:
+		logging.debug('ERROR: test-case ' + id + ' has unlisted class ' + action + ' ##CHECK xml_class_list.yml')
+		resp=False
+	else:
+		resp=True
+	return resp
+
+
+#assigning parameters to object instance attributes (even if the attributes do not exist !!)
+def AssignParams(params_dict):
+
+	for key,value in params_dict.items():
+		setattr(CiTestObj, key, value)
+		setattr(RAN, key, value)
+		setattr(HTML, key, value)
+		setattr(ldpc, key, value)
+
+
 
 def GetParametersFromXML(action):
 	if action == 'Build_eNB':
-		RAN.SetBuild_eNB_args(test.findtext('Build_eNB_args'))
+		RAN.Build_eNB_args=test.findtext('Build_eNB_args')
 		forced_workspace_cleanup = test.findtext('forced_workspace_cleanup')
 		if (forced_workspace_cleanup is None):
-			RAN.SetBuild_eNB_forced_workspace_cleanup(False)
+			RAN.Build_eNB_forced_workspace_cleanup=False
 		else:
 			if re.match('true', forced_workspace_cleanup, re.IGNORECASE):
-				RAN.SetBuild_eNB_forced_workspace_cleanup(True)
+				RAN.Build_eNB_forced_workspace_cleanup=True
 			else:
-				RAN.SetBuild_eNB_forced_workspace_cleanup(False)
-		RAN.SeteNB_instance(test.findtext('eNB_instance'))
-		if (RAN.GeteNB_instance() is None):
-			RAN.SeteNB_instance('0')
-		RAN.SeteNB_serverId(test.findtext('eNB_serverId'))
-		if (RAN.GeteNB_serverId() is None):
-			RAN.SeteNB_serverId('0')
+				RAN.Build_eNB_forced_workspace_cleanup=False
+		eNB_instance=test.findtext('eNB_instance')
+		if (eNB_instance is None):
+			RAN.eNB_instance=0
+		else:
+			RAN.eNB_instance=int(eNB_instance)
+		RAN.eNB_serverId=test.findtext('eNB_serverId')
+		if (RAN.eNB_serverId is None):
+			RAN.eNB_serverId='0'
 		xmlBgBuildField = test.findtext('backgroundBuild')
 		if (xmlBgBuildField is None):
-			RAN.SetbackgroundBuild(False)
+			RAN.backgroundBuild=False
 		else:
 			if re.match('true', xmlBgBuildField, re.IGNORECASE):
-				RAN.SetbackgroundBuild(True)
+				RAN.backgroundBuild=True
 			else:
-				RAN.SetbackgroundBuild(False)
+				RAN.backgroundBuild=False
 
 	if action == 'WaitEndBuild_eNB':
-		RAN.SetBuild_eNB_args(test.findtext('Build_eNB_args'))
-		RAN.SeteNB_instance(test.findtext('eNB_instance'))
-		if (RAN.GeteNB_instance() is None):
-			RAN.SeteNB_instance('0')
-		RAN.SeteNB_serverId(test.findtext('eNB_serverId'))
-		if (RAN.GeteNB_serverId() is None):
-			RAN.SeteNB_serverId('0')
+		RAN.Build_eNB_args=test.findtext('Build_eNB_args')
+		eNB_instance=test.findtext('eNB_instance')
+		if (eNB_instance is None):
+			RAN.eNB_instance=0
+		else:
+			RAN.eNB_instance=int(eNB_instance)
+		RAN.eNB_serverId=test.findtext('eNB_serverId')
+		if (RAN.eNB_serverId is None):
+			RAN.eNB_serverId='0'
 
 	if action == 'Initialize_eNB':
-		RAN.SetInitialize_eNB_args(test.findtext('Initialize_eNB_args'))
-		RAN.SeteNB_instance(test.findtext('eNB_instance'))
-		if (RAN.GeteNB_instance() is None):
-			RAN.SeteNB_instance('0')
-		RAN.SeteNB_serverId(test.findtext('eNB_serverId'))
-		if (RAN.GeteNB_serverId() is None):
-			RAN.SeteNB_serverId('0')
-		CiTestObj.air_interface = test.findtext('air_interface')
-		if (CiTestObj.air_interface is None):
-			CiTestObj.air_interface = 'lte'
+		RAN.Initialize_eNB_args=test.findtext('Initialize_eNB_args')
+		eNB_instance=test.findtext('eNB_instance')
+		if (eNB_instance is None):
+			RAN.eNB_instance=0
 		else:
-			CiTestObj.air_interface = CiTestObj.air_interface.lower()
-		RAN.Setair_interface(CiTestObj.air_interface)
+			RAN.eNB_instance=int(eNB_instance)
+		RAN.eNB_serverId=test.findtext('eNB_serverId')
+		if (RAN.eNB_serverId is None):
+			RAN.eNB_serverId='0'
+			
+		#local variable air_interface
+		air_interface = test.findtext('air_interface')		
+		if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']):
+			RAN.air_interface[RAN.eNB_instance] = 'lte-softmodem'
+		elif (air_interface.lower() in ['nr','lte']):
+			RAN.air_interface[RAN.eNB_instance] = air_interface.lower() +'-softmodem'
+		else :
+			RAN.air_interface[RAN.eNB_instance] = 'ocp-enb'
 
 	if action == 'Terminate_eNB':
-		RAN.SeteNB_instance(test.findtext('eNB_instance'))
-		if (RAN.GeteNB_instance() is None):
-			RAN.SeteNB_instance('0')
-		RAN.SeteNB_serverId(test.findtext('eNB_serverId'))
-		if (RAN.GeteNB_serverId() is None):
-			RAN.SeteNB_serverId('0')
-		CiTestObj.air_interface = test.findtext('air_interface')
-		if (CiTestObj.air_interface is None):
-			CiTestObj.air_interface = 'lte'
+		eNB_instance=test.findtext('eNB_instance')
+		if (eNB_instance is None):
+			RAN.eNB_instance=0
 		else:
-			CiTestObj.air_interface = CiTestObj.air_interface.lower()
-		RAN.Setair_interface(CiTestObj.air_interface)
+			RAN.eNB_instance=int(eNB_instance)
+		RAN.eNB_serverId=test.findtext('eNB_serverId')
+		if (RAN.eNB_serverId is None):
+			RAN.eNB_serverId='0'
+			
+		#local variable air_interface
+		air_interface = test.findtext('air_interface')		
+		if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']):
+			RAN.air_interface[RAN.eNB_instance] = 'lte-softmodem'
+		elif (air_interface.lower() in ['nr','lte']):
+			RAN.air_interface[RAN.eNB_instance] = air_interface.lower() +'-softmodem'
+		else :
+			RAN.air_interface[RAN.eNB_instance] = 'ocp-enb'
 
 	if action == 'Attach_UE':
 		nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach')
@@ -3160,19 +3207,38 @@ def GetParametersFromXML(action):
 
 	if action == 'Initialize_OAI_UE':
 		CiTestObj.Initialize_OAI_UE_args = test.findtext('Initialize_OAI_UE_args')
-		CiTestObj.UE_instance = test.findtext('UE_instance')
-		if (CiTestObj.UE_instance is None):
-			CiTestObj.UE_instance = '0'
-		CiTestObj.air_interface = test.findtext('air_interface')
-		if (CiTestObj.air_interface is None):
-			CiTestObj.air_interface = 'lte'
+		UE_instance = test.findtext('UE_instance')
+		if (UE_instance is None):
+			CiTestObj.UE_instance = 0
 		else:
-			CiTestObj.air_interface = CiTestObj.air_interface.lower()
+			CiTestObj.UE_instance = UE_instance
+			
+		#local variable air_interface
+		air_interface = test.findtext('air_interface')		
+		if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']):
+			CiTestObj.air_interface = 'lte-uesoftmodem'
+		elif (air_interface.lower() in ['nr','lte']):
+			CiTestObj.air_interface = air_interface.lower() +'-uesoftmodem'
+		else :
+			#CiTestObj.air_interface = 'ocp-enb'
+			logging.error('OCP UE -- NOT SUPPORTED')
 
 	if action == 'Terminate_OAI_UE':
-		RAN.SeteNB_instance(test.findtext('UE_instance'))
-		if (CiTestObj.UE_instance is None):
+		UE_instance=test.findtext('UE_instance')
+		if (UE_instance is None):
 			CiTestObj.UE_instance = '0'
+		else:
+			CiTestObj.UE_instance = int(UE_instance)
+		
+		#local variable air_interface
+		air_interface = test.findtext('air_interface')		
+		if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']):
+			CiTestObj.air_interface = 'lte-uesoftmodem'
+		elif (air_interface.lower() in ['nr','lte']):
+			CiTestObj.air_interface = air_interface.lower() +'-uesoftmodem'
+		else :
+			#CiTestObj.air_interface = 'ocp-enb'
+			logging.error('OCP UE -- NOT SUPPORTED')
 
 	if action == 'Ping' or action == 'Ping_CatM_module':
 		CiTestObj.ping_args = test.findtext('ping_args')
@@ -3227,6 +3293,9 @@ def GetParametersFromXML(action):
 
 	if action == 'Run_PhySim':
 		ldpc.runargs = test.findtext('physim_run_args')
+		
+	if action == 'COTS_UE_Airplane':
+		COTS_UE.runargs = test.findtext('cots_ue_airplane_args')
 
 #check if given test is in list
 #it is in list if one of the strings in 'list' is at the beginning of 'test'
@@ -3240,207 +3309,88 @@ def test_in_list(test, list):
 def receive_signal(signum, frame):
 	sys.exit(1)
 
+
+
+
+
+
 #-----------------------------------------------------------
-# Parameter Check
+# MAIN PART
 #-----------------------------------------------------------
+
+#loading xml action list from yaml
+import yaml
+xml_class_list_file=''
+if (os.path.isfile('xml_class_list.yml')):
+	xml_class_list_file='xml_class_list.yml'
+if (os.path.isfile('ci-scripts/xml_class_list.yml')):
+	xml_class_list_file='ci-scripts/xml_class_list.yml'
+with open(xml_class_list_file,'r') as file:
+    # The FullLoader parameter handles the conversion from YAML
+    # scalar values to Python the dictionary format
+    xml_class_list = yaml.load(file,Loader=yaml.FullLoader)
+
 mode = ''
-CiTestObj = OaiCiTest()
 
-import sshconnection 
-import epc
-import helpreadme as HELP
-import ran
-import html
-import constants
+CiTestObj = OaiCiTest()
  
 SSH = sshconnection.SSHConnection()
 EPC = epc.EPCManagement()
 RAN = ran.RANManagement()
 HTML = html.HTMLManagement()
 
-EPC.SetHtmlObj(HTML)
-RAN.SetHtmlObj(HTML)
-RAN.SetEpcObj(EPC)
+EPC.htmlObj=HTML
+RAN.htmlObj=HTML
+RAN.epcObj=EPC
+
 
-import cls_physim           #class PhySim for physical simulators build and test
 ldpc=cls_physim.PhySim()    #create an instance for LDPC test using GPU or CPU build
 
-argvs = sys.argv
-argc = len(argvs)
-cwd = os.getcwd()
 
-while len(argvs) > 1:
-	myArgv = argvs.pop(1)	# 0th is this file's name
 
-	if re.match('^\-\-help$', myArgv, re.IGNORECASE):
-		HELP.GenericHelp(CONST.Version)
-		sys.exit(0)
-	elif re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE)
-		mode = matchReg.group(1)
-	elif re.match('^\-\-eNBRepository=(.+)$|^\-\-ranRepository(.+)$', myArgv, re.IGNORECASE):
-		if re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE):
-			matchReg = re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE)
-		else:
-			matchReg = re.match('^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE)
-		CiTestObj.ranRepository = matchReg.group(1)
-		RAN.SetranRepository(matchReg.group(1))
-		HTML.SetranRepository(matchReg.group(1))
-		ldpc.ranRepository=matchReg.group(1)
-	elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE):
-		if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE):
-			matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE)
-		else:
-			matchReg = re.match('^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE)
-		doMerge = matchReg.group(1)
-		ldpc.ranAllowMerge=matchReg.group(1)
-		if ((doMerge == 'true') or (doMerge == 'True')):
-			CiTestObj.ranAllowMerge = True
-			RAN.SetranAllowMerge(True)
-			HTML.SetranAllowMerge(True)
-	elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE):
-		if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE):
-			matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE)
-		else:
-			matchReg = re.match('^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE)
-		CiTestObj.ranBranch = matchReg.group(1)
-		RAN.SetranBranch(matchReg.group(1))
-		HTML.SetranBranch(matchReg.group(1))
-		ldpc.ranBranch=matchReg.group(1)
-	elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE):
-		if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE):
-			matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE)
-		else:
-			matchReg = re.match('^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE)
-		CiTestObj.ranCommitID = matchReg.group(1)
-		RAN.SetranCommitID(matchReg.group(1))
-		HTML.SetranCommitID(matchReg.group(1))
-		ldpc.ranCommitID=matchReg.group(1)
-	elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE):
-		if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE):
-			matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE)
-		else:
-			matchReg = re.match('^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE)
-		CiTestObj.ranTargetBranch = matchReg.group(1)
-		RAN.SetranTargetBranch(matchReg.group(1))
-		HTML.SetranTargetBranch(matchReg.group(1))
-		ldpc.ranTargetBranch=matchReg.group(1)
-	elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE):
-		if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE):
-			matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE)
-			RAN.SeteNBIPAddress(matchReg.group(1))
-			ldpc.eNBIpAddr=matchReg.group(1)
-		elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE):
-			matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE)
-			RAN.SeteNB1IPAddress(matchReg.group(1))
-		elif re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE):
-			matchReg = re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE)
-			RAN.SeteNB2IPAddress(matchReg.group(1))
-	elif re.match('^\-\-eNBUserName=(.+)$|^\-\-eNB[1-2]UserName=(.+)$', myArgv, re.IGNORECASE):
-		if re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE):
-			matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE)
-			RAN.SeteNBUserName(matchReg.group(1))
-			ldpc.eNBUserName=matchReg.group(1)
-		elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE):
-			matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE)
-			RAN.SeteNB1UserName(matchReg.group(1))
-		elif re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE):
-			matchReg = re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE)
-			RAN.SeteNB2UserName(matchReg.group(1))
-	elif re.match('^\-\-eNBPassword=(.+)$|^\-\-eNB[1-2]Password=(.+)$', myArgv, re.IGNORECASE):
-		if re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE):
-			matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE)
-			RAN.SeteNBPassword(matchReg.group(1))
-			ldpc.eNBPassWord=matchReg.group(1)
-		elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE):
-			matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE)
-			RAN.SeteNB1Password(matchReg.group(1))
-		elif re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE):
-			matchReg = re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE)
-			RAN.SeteNB2Password(matchReg.group(1))
-	elif re.match('^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
-		if re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE):
-			matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE)
-			RAN.SeteNBSourceCodePath(matchReg.group(1))
-			ldpc.eNBSourceCodePath=matchReg.group(1)
-		elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
-			matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
-			RAN.SeteNB1SourceCodePath(matchReg.group(1))
-		elif re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
-			matchReg = re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
-			RAN.SeteNB2SourceCodePath(matchReg.group(1))
-	elif re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE)
-		EPC.SetIPAddress(matchReg.group(1))
-	elif re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE)
-		EPC.SetUserName(matchReg.group(1))
-	elif re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE)
-		EPC.SetPassword(matchReg.group(1))
-	elif re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE)
-		EPC.SetSourceCodePath(matchReg.group(1))
-	elif re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE)
-		if re.match('OAI', matchReg.group(1), re.IGNORECASE) or re.match('ltebox', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-CUPS', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-Docker', matchReg.group(1), re.IGNORECASE):
-			EPC.SetType(matchReg.group(1))
-		else:
-			sys.exit('Invalid EPC Type: ' + matchReg.group(1) + ' -- (should be OAI or ltebox or OAI-Rel14-CUPS or OAI-Rel14-Docker)')
-	elif re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE)
-		EPC.SetContainerPrefix(matchReg.group(1))
-	elif re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE)
-		CiTestObj.ADBIPAddress = matchReg.group(1)
-	elif re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE)
-		CiTestObj.ADBUserName = matchReg.group(1)
-	elif re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE)
-		if re.match('centralized', matchReg.group(1), re.IGNORECASE) or re.match('distributed', matchReg.group(1), re.IGNORECASE):
-			if re.match('distributed', matchReg.group(1), re.IGNORECASE):
-				CiTestObj.ADBCentralized = False
-			else:
-				CiTestObj.ADBCentralized = True
-		else:
-			sys.exit('Invalid ADB Type: ' + matchReg.group(1) + ' -- (should be centralized or distributed)')
-	elif re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE)
-		CiTestObj.ADBPassword = matchReg.group(1)
-	elif re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE)
-		CiTestObj.testXMLfiles.append(matchReg.group(1))
-		HTML.SettestXMLfiles(matchReg.group(1))
-		HTML.SetnbTestXMLfiles(HTML.GetnbTestXMLfiles()+1)
-	elif re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE)
-		CiTestObj.UEIPAddress = matchReg.group(1)
-	elif re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE)
-		CiTestObj.UEUserName = matchReg.group(1)
-	elif re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE)
-		CiTestObj.UEPassword = matchReg.group(1)
-	elif re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE)
-		CiTestObj.UESourceCodePath = matchReg.group(1)
-	elif re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE)
-		finalStatus = matchReg.group(1)
-		if ((finalStatus == 'true') or (finalStatus == 'True')):
-			CiTestObj.finalStatus = True
-	else:
-		HELP.GenericHelp(CONST.Version)
-		sys.exit('Invalid Parameter: ' + myArgv)
+#-----------------------------------------------------------
+# Parsing Command Line Arguments
+#-----------------------------------------------------------
+
+import args_parse
+py_param_file_present, py_params, mode = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,EPC,ldpc,HELP)
+
+
+
+#-----------------------------------------------------------
+# TEMPORARY params management
+#-----------------------------------------------------------
+#temporary solution for testing:
+if py_param_file_present == True:
+	AssignParams(py_params)
+
+#for debug
+#print(RAN.__dict__) 
+#print(CiTestObj.__dict__) 
+#print(HTML.__dict__) 
+#print(ldpc.__dict__) 
+#for debug
+
+
+#-----------------------------------------------------------
+# COTS UE instanciation
+#-----------------------------------------------------------
+#COTS_UE instanciation can only be done here for the moment, due to code architecture
+COTS_UE=cls_cots_ue.CotsUe('oppo', CiTestObj.UEIPAddress, CiTestObj.UEUserName,CiTestObj.UEPassword)
+
+
+#-----------------------------------------------------------
+# XML class (action) analysis
+#-----------------------------------------------------------
+cwd = os.getcwd()
 
 if re.match('^TerminateeNB$', mode, re.IGNORECASE):
-	if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '':
+	if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '':
 		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
-	RAN.SeteNB_serverId('0')
-	RAN.SeteNB_instance('0')
-	RAN.SeteNBSourceCodePath('/tmp/')
+	RAN.eNB_serverId='0'
+	RAN.eNB_instance=0
+	RAN.eNBSourceCodePath='/tmp/'
 	RAN.TerminateeNB()
 elif re.match('^TerminateUE$', mode, re.IGNORECASE):
 	if (CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == ''):
@@ -3455,52 +3405,52 @@ elif re.match('^TerminateOAIUE$', mode, re.IGNORECASE):
 	signal.signal(signal.SIGUSR1, receive_signal)
 	CiTestObj.TerminateOAIUE()
 elif re.match('^TerminateHSS$', mode, re.IGNORECASE):
-	if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '':
+	if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '':
 		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
 	EPC.TerminateHSS()
 elif re.match('^TerminateMME$', mode, re.IGNORECASE):
-	if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '':
+	if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '':
 		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
 	EPC.TerminateMME()
 elif re.match('^TerminateSPGW$', mode, re.IGNORECASE):
-	if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '':
+	if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath== '':
 		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
 	EPC.TerminateSPGW()
 elif re.match('^LogCollectBuild$', mode, re.IGNORECASE):
-	if (RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '') and (CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == ''):
+	if (RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '') and (CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == ''):
 		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
 	CiTestObj.LogCollectBuild()
 elif re.match('^LogCollecteNB$', mode, re.IGNORECASE):
-	if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '':
+	if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '':
 		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
 	RAN.LogCollecteNB()
 elif re.match('^LogCollectHSS$', mode, re.IGNORECASE):
-	if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '':
+	if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '':
 		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
 	EPC.LogCollectHSS()
 elif re.match('^LogCollectMME$', mode, re.IGNORECASE):
-	if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '':
+	if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '':
 		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
 	EPC.LogCollectMME()
 elif re.match('^LogCollectSPGW$', mode, re.IGNORECASE):
-	if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '':
+	if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '':
 		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
 	EPC.LogCollectSPGW()
 elif re.match('^LogCollectPing$', mode, re.IGNORECASE):
-	if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '':
+	if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '':
 		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
 	CiTestObj.LogCollectPing()
 elif re.match('^LogCollectIperf$', mode, re.IGNORECASE):
-	if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '':
+	if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '':
 		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
 	CiTestObj.LogCollectIperf()
@@ -3515,7 +3465,7 @@ elif re.match('^InitiateHtml$', mode, re.IGNORECASE):
 		sys.exit('Insufficient Parameter')
 	count = 0
 	foundCount = 0
-	while (count < HTML.GetnbTestXMLfiles()):
+	while (count < HTML.nbTestXMLfiles):
 		#xml_test_file = cwd + "/" + CiTestObj.testXMLfiles[count]
 		xml_test_file = sys.path[0] + "/" + CiTestObj.testXMLfiles[count]
 		if (os.path.isfile(xml_test_file)):
@@ -3524,21 +3474,21 @@ elif re.match('^InitiateHtml$', mode, re.IGNORECASE):
 			except:
 				print("Error while parsing file: " + xml_test_file)
 			xmlRoot = xmlTree.getroot()
-			HTML.SethtmlTabRefs(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count)))
-			HTML.SethtmlTabNames(xmlRoot.findtext('htmlTabName',default='test-tab-' + str(count)))
-			HTML.SethtmlTabIcons(xmlRoot.findtext('htmlTabIcon',default='info-sign'))
+			HTML.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count)))
+			HTML.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='test-tab-' + str(count)))
+			HTML.htmlTabIcons.append(xmlRoot.findtext('htmlTabIcon',default='info-sign'))
 			foundCount += 1
 		count += 1
-	if foundCount != HTML.GetnbTestXMLfiles():
-		HTML.SetnbTestXMLfiles(foundCount)
+	if foundCount != HTML.nbTestXMLfiles:
+		HTML.nbTestXMLfiles=foundCount
 	
 	if (CiTestObj.ADBIPAddress != 'none'):
 		terminate_ue_flag = False
 		CiTestObj.GetAllUEDevices(terminate_ue_flag)
 		CiTestObj.GetAllCatMDevices(terminate_ue_flag)
 		HTML.SethtmlUEConnected(len(CiTestObj.UEDevices) + len(CiTestObj.CatMDevices))
-		HTML.SethtmlNb_Smartphones(len(CiTestObj.UEDevices))
-		HTML.SethtmlNb_CATM_Modules(len(CiTestObj.CatMDevices))
+		HTML.htmlNb_Smartphones=len(CiTestObj.UEDevices)
+		HTML.htmlNb_CATM_Modules=len(CiTestObj.CatMDevices)
 	HTML.CreateHtmlHeader(CiTestObj.ADBIPAddress)
 elif re.match('^FinalizeHtml$', mode, re.IGNORECASE):
 	logging.debug('\u001B[1m----------------------------------------\u001B[0m')
@@ -3550,19 +3500,19 @@ elif re.match('^FinalizeHtml$', mode, re.IGNORECASE):
 	HTML.CreateHtmlFooter(CiTestObj.finalStatus)
 elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re.IGNORECASE):
 	if re.match('^TesteNB$', mode, re.IGNORECASE):
-		if RAN.GeteNBIPAddress() == '' or RAN.GetranRepository() == '' or RAN.GetranBranch() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '' or EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '' or CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == '':
+		if RAN.eNBIPAddress == '' or RAN.ranRepository == '' or RAN.ranBranch == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '' or EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '' or CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == '':
 			HELP.GenericHelp(CONST.Version)
-			if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '' or EPC.GetType() == '':
-				HELP.EPCSrvHelp(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), EPC.GetSourceCodePath(), EPC.GetType())
-			if RAN.GetranRepository() == '':
-				HELP.GitSrvHelp(RAN.GetranRepository(), RAN.GetranBranch(), RAN.GetranCommitID(), RAN.GetranAllowMerge(), RAN.GetranTargetBranch())
-			if RAN.GeteNBIPAddress() == ''  or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '':
-				HELP.eNBSrvHelp(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath())
+			if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '' or EPC.Type == '':
+				HELP.EPCSrvHelp(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath, EPC.Type)
+			if RAN.ranRepository == '':
+				HELP.GitSrvHelp(RAN.ranRepository, RAN.ranBranch, RAN.ranCommitID, RAN.ranAllowMerge, RAN.ranTargetBranch)
+			if RAN.eNBIPAddress == ''  or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '':
+				HELP.eNBSrvHelp(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath)
 			sys.exit('Insufficient Parameter')
 
-		if (EPC.GetIPAddress() != '') and (EPC.GetIPAddress() != 'none'):
-			SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), cwd + "/tcp_iperf_stats.awk", "/tmp")
-			SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), cwd + "/active_net_interfaces.awk", "/tmp")
+		if (EPC.IPAddress!= '') and (EPC.IPAddress != 'none'):
+			SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, cwd + "/tcp_iperf_stats.awk", "/tmp")
+			SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, cwd + "/active_net_interfaces.awk", "/tmp")
 	else:
 		if CiTestObj.UEIPAddress == '' or CiTestObj.ranRepository == '' or CiTestObj.ranBranch == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == '':
 			HELP.GenericHelp(CONST.Version)
@@ -3570,7 +3520,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 
 	#read test_case_list.xml file
 	# if no parameters for XML file, use default value
-	if (HTML.GetnbTestXMLfiles() != 1):
+	if (HTML.nbTestXMLfiles != 1):
 		xml_test_file = cwd + "/test_case_list.xml"
 	else:
 		xml_test_file = cwd + "/" + CiTestObj.testXMLfiles[0]
@@ -3580,9 +3530,9 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 
 	exclusion_tests=xmlRoot.findtext('TestCaseExclusionList',default='')
 	requested_tests=xmlRoot.findtext('TestCaseRequestedList',default='')
-	if (HTML.GetnbTestXMLfiles() == 1):
-		HTML.SethtmlTabRefs(xmlRoot.findtext('htmlTabRef',default='test-tab-0'))
-		HTML.SethtmlTabNames(xmlRoot.findtext('htmlTabName',default='Test-0'))
+	if (HTML.nbTestXMLfiles == 1):
+		HTML.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-0'))
+		HTML.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-0'))
 		repeatCount = xmlRoot.findtext('repeatCount',default='1')
 		CiTestObj.repeatCounts.append(int(repeatCount))
 	all_tests=xmlRoot.findall('testCase')
@@ -3610,7 +3560,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 		else:
 			logging.debug('ERROR: requested test is invalidly formatted: ' + test)
 			sys.exit(1)
-	if (EPC.GetIPAddress() != '') and (EPC.GetIPAddress() != 'none'):
+	if (EPC.IPAddress != '') and (EPC.IPAddress != 'none'):
 		CiTestObj.CheckFlexranCtrlInstallation()
 		EPC.SetMmeIPAddress()
 
@@ -3635,29 +3585,29 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 	HTML.CreateHtmlTabHeader()
 
 	CiTestObj.FailReportCnt = 0
-	RAN.SetprematureExit(True)
-	HTML.SetstartTime(int(round(time.time() * 1000)))
-	while CiTestObj.FailReportCnt < CiTestObj.repeatCounts[0] and RAN.GetprematureExit():
-		RAN.SetprematureExit(False)
+	RAN.prematureExit=True
+	HTML.startTime=int(round(time.time() * 1000))
+	while CiTestObj.FailReportCnt < CiTestObj.repeatCounts[0] and RAN.prematureExit:
+		RAN.prematureExit=False
 		# At every iteratin of the retry loop, a separator will be added
 		# pass CiTestObj.FailReportCnt as parameter of HTML.CreateHtmlRetrySeparator
 		HTML.CreateHtmlRetrySeparator(CiTestObj.FailReportCnt)
 		for test_case_id in todo_tests:
-			if RAN.GetprematureExit():
+			if RAN.prematureExit:
 				break
 			for test in all_tests:
-				if RAN.GetprematureExit():
+				if RAN.prematureExit:
 					break
 				id = test.get('id')
 				if test_case_id != id:
 					continue
 				CiTestObj.testCase_id = id
-				HTML.SettestCase_id(CiTestObj.testCase_id)
-				EPC.SetTestCase_id(CiTestObj.testCase_id)
+				HTML.testCase_id=CiTestObj.testCase_id
+				EPC.testCase_id=CiTestObj.testCase_id
 				CiTestObj.desc = test.findtext('desc')
-				HTML.Setdesc(CiTestObj.desc)
+				HTML.desc=CiTestObj.desc
 				action = test.findtext('class')
-				if (CheckClassValidity(action, id) == False):
+				if (CheckClassValidity(xml_class_list, action, id) == False):
 					continue
 				CiTestObj.ShowTestID()
 				GetParametersFromXML(action)
@@ -3672,7 +3622,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 				elif action == 'Initialize_eNB':
 					check_eNB = False
 					check_OAI_UE = False
-					RAN.SetpStatus(CiTestObj.CheckProcessExist(check_eNB, check_OAI_UE))
+					RAN.pStatus=CiTestObj.CheckProcessExist(check_eNB, check_OAI_UE)
 
 					RAN.InitializeeNB()
 				elif action == 'Terminate_eNB':
@@ -3738,16 +3688,20 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 					if ldpc.exitStatus==1:sys.exit()
 				elif action == 'Run_PhySim':
 					HTML=ldpc.Run_PhySim(HTML,CONST,id)
+				elif action == 'COTS_UE_Airplane':
+					COTS_UE.Set_Airplane(COTS_UE.runargs)
 				else:
-					sys.exit('Invalid action')
+					sys.exit('Invalid class (action) from xml')
 		CiTestObj.FailReportCnt += 1
-	if CiTestObj.FailReportCnt == CiTestObj.repeatCounts[0] and RAN.GetprematureExit():
+	if CiTestObj.FailReportCnt == CiTestObj.repeatCounts[0] and RAN.prematureExit:
 		logging.debug('Testsuite failed ' + str(CiTestObj.FailReportCnt) + ' time(s)')
 		HTML.CreateHtmlTabFooter(False)
 		sys.exit('Failed Scenario')
 	else:
 		logging.info('Testsuite passed after ' + str(CiTestObj.FailReportCnt) + ' time(s)')
 		HTML.CreateHtmlTabFooter(True)
+elif re.match('^LoadParams$', mode, re.IGNORECASE):
+	pass
 else:
 	HELP.GenericHelp(CONST.Version)
 	sys.exit('Invalid mode')
diff --git a/ci-scripts/py_params.yaml b/ci-scripts/py_params.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..303d5d100660b8d2608a67f58e4950690882ffb8
--- /dev/null
+++ b/ci-scripts/py_params.yaml
@@ -0,0 +1,53 @@
+eNBRepository : b
+ranRepository : c
+eNB_AllowMerge : 
+ranAllowMerge : 
+eNBBranch : f
+ranBranch : g
+eNBCommitID :  
+ranCommitID : i
+eNBTargetBranch : j
+ranTargetBranch : k
+
+nodes : 
+  - type : eNB
+    IPAddress : 001.1.1
+    UserName : toto
+    Password : qwe
+    SourceCodePath : l
+  - type : gNB
+    IPAddress : 002.2.2
+    UserName : tata
+    Password : asd
+    SourceCodePath : m  
+  - type : eNB
+    IPAddress : 003.3.3
+    UserName : titi
+    Password : zxc
+    SourceCodePath : n
+  - type : gNB
+    IPAddress : 004.4.4
+    UserName : caca
+    Password : pepe
+    SourceCodePath :  o   
+
+EPCIPAddress : p
+EPCUserName : q
+EPCPassword : r
+EPCSourceCodePath : s
+EPCType : t
+EPCContainerPrefix : u
+
+ADBIPAddress : v
+ADBUserName : w
+ADBType : x
+ADBPassword : y
+
+XMLTestFile : z
+
+UEIPAddress : qqq
+UEUserName : www
+UEPassword : eee
+UESourceCodePath : yyy
+
+finalStatus : bbb
\ No newline at end of file
diff --git a/ci-scripts/py_params_template.yaml b/ci-scripts/py_params_template.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..aaf31c1576527dc08985a37dfe1dd2b97eca8d64
--- /dev/null
+++ b/ci-scripts/py_params_template.yaml
@@ -0,0 +1,97 @@
+eNBRepository : b
+ranRepository : c
+eNB_AllowMerge : 
+ranAllowMerge : 
+eNBBranch : f
+ranBranch : g
+eNBCommitID :  
+ranCommitID : i
+eNBTargetBranch : j
+ranTargetBranch : k
+
+
+RAN:
+  RAN_inst_0:
+    name : RAN_1
+    nodes : 
+    - type : eNB
+      IPAddress : 001.1.1
+      UserName : toto
+      Password : qwe
+      SourceCodePath : l
+    - type : gNB
+      IPAddress : 002.2.2
+      UserName : tata
+      Password : asd
+      SourceCodePath : m  
+    - type : eNB
+      IPAddress : 003.3.3
+      UserName : titi
+      Password : zxc
+      SourceCodePath : n
+    - type : gNB
+      IPAddress : 004.4.4
+      UserName : caca
+      Password : pepe
+      SourceCodePath :  o        
+  RAN_inst_1:
+    name : RAN_2
+    nodes : 
+    - type : eNB
+      IPAddress : 101.1.1
+      UserName : toto
+      Password : qwe
+      SourceCodePath : l
+    - type : gNB
+      IPAddress : 102.2.2
+      UserName : zaza
+      Password : asd
+      SourceCodePath : m  
+    - type : eNB
+      IPAddress : 103.3.3
+      UserName : zizi
+      Password : zxc
+      SourceCodePath : n
+    - type : gNB
+      IPAddress : 104.4.4
+      UserName : aaaa
+      Password : pepe
+      SourceCodePath :  o   
+
+
+
+EPC:
+  EPC_inst_0:
+    EPCIPAddress : p
+    EPCUserName : q
+    EPCPassword : r
+    EPCSourceCodePath : s
+    EPCType : t
+    EPCContainerPrefix : u
+
+ADB:
+  ADBIPAddress : v
+  ADBUserName : w
+  ADBType : x
+  ADBPassword : y
+
+
+UE:
+  UE_inst_0:
+    name : UE_1 
+    type :
+    UEIPAddress : qqq  
+    UEUserName : www
+    UEPassword : eee
+    UESourceCodePath : yyy
+  UE_inst_1:
+    name : UE_2
+    type :
+    UEIPAddress : bloblob  
+    UEUserName : gwou
+    UEPassword : zebu
+    UESourceCodePath : pop
+
+
+XMLTestFile : z
+finalStatus : bbb
\ No newline at end of file
diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py
index 287c18021e2cf2cabbeafe55a81a6b965e73612e..96f28e21fe3f58e19d56510c3fcac22645a2df05 100644
--- a/ci-scripts/ran.py
+++ b/ci-scripts/ran.py
@@ -77,8 +77,8 @@ class RANManagement():
 		self.backgroundBuildTestId = ['', '', '']
 		self.Build_eNB_forced_workspace_cleanup = False
 		self.Initialize_eNB_args = ''
-		self.air_interface = 'lte'
-		self.eNB_instance = ''
+		self.air_interface = ['', '', ''] #changed from 'lte' to '' may lead to side effects in main
+		self.eNB_instance = 0
 		self.eNB_serverId = ''
 		self.eNBLogFiles = ['', '', '']
 		self.eNBOptions = ['', '', '']
@@ -91,140 +91,7 @@ class RANManagement():
 		self.htmlObj = None
 		self.epcObj = None
 
-#-----------------------------------------------------------
-# Setters and Getters on Public members
-#-----------------------------------------------------------
-
-	def SetHtmlObj(self, obj):
-		self.htmlObj = obj
-	def SetEpcObj(self, obj):
-		self.epcObj = obj
-
-	def SetflexranCtrlInstalled(self,fxrctin):
-		self.flexranCtrlInstalled = fxrctin
-	def GetflexranCtrlInstalled(self):
-		return self.flexranCtrlInstalled
-	def SetflexranCtrlStarted(self,fxrctst):
-		self.flexranCtrlStarted = fxrctst
-	def GetflexranCtrlStarted(self):
-		return self.flexranCtrlStarted
-	def SetpStatus(self, pSt):
-		self.pStatus = pSt
-	def SetranRepository(self, repository):
-		self.ranRepository = repository
-	def GetranRepository(self):
-		return self.ranRepository
-	def SetranBranch(self, branch):
-		self.ranBranch = branch
-	def GetranBranch(self):
-		return self.ranBranch
-	def SetranCommitID(self, commitid):
-		self.ranCommitID = commitid
-	def GetranCommitID(self):
-		return self.ranCommitID
-	def SeteNB_serverId(self, enbsrvid):
-		self.eNB_serverId = enbsrvid
-	def GeteNB_serverId(self):
-		return self.eNB_serverId
-	def SeteNBIPAddress(self, enbip):
-		self.eNBIPAddress = enbip
-	def GeteNBIPAddress(self):
-		return self.eNBIPAddress
-	def SeteNBUserName(self, enbusr):
-		self.eNBUserName = enbusr
-	def GeteNBUserName(self):
-		return self.eNBUserName
-	def SeteNBPassword(self, enbpw):
-		self.eNBPassword = enbpw
-	def GeteNBPassword(self):
-		return self.eNBPassword
-	def SeteNBSourceCodePath(self, enbcodepath):
-		self.eNBSourceCodePath = enbcodepath
-	def GeteNBSourceCodePath(self):
-		return self.eNBSourceCodePath
-	def SetranAllowMerge(self, merge):
-		self.ranAllowMerge = merge
-	def GetranAllowMerge(self):
-		return self.ranAllowMerge
-	def SetranTargetBranch(self, tbranch):
-		self.ranTargetBranch = tbranch
-	def GetranTargetBranch(self):
-		return self.ranTargetBranch
-	def SetBuild_eNB_args(self, enbbuildarg):
-		self.Build_eNB_args = enbbuildarg
-	def GetBuild_eNB_args(self):
-		return self.Build_eNB_args
-	def SetInitialize_eNB_args(self, initenbarg):
-		self.Initialize_eNB_args = initenbarg
-	def GetInitialize_eNB_args(self):
-		return self.Initialize_eNB_args
-	def SetbackgroundBuild(self, bkbuild):
-		self.backgroundBuild = bkbuild
-	def GetbackgroundBuild(self):
-		return self.backgroundBuild
-	def SetbackgroundBuildTestId(self, bkbuildid):
-		self.backgroundBuildTestId = bkbuildid
-	def GetbackgroundBuildTestId(self):
-		return self.backgroundBuildTestId
-	def SetBuild_eNB_forced_workspace_cleanup(self, fcdwspclean):
-		self.Build_eNB_forced_workspace_cleanup = fcdwspclean
-	def GetBuild_eNB_forced_workspace_cleanup(self):
-		return self.Build_eNB_forced_workspace_cleanup
-	def Setair_interface(self, airif):
-		self.air_interface = airif
-	def Getair_interface(self):
-		return self.air_interface
-	def SeteNB_instance(self, enbinst):
-		self.eNB_instance = enbinst
-	def GeteNB_instance(self):
-		return self.eNB_instance
-
-	def SeteNBLogFile(self, enblog, idx):
-		self.eNBLogFiles[idx] = enblog
-	def GeteNBLogFile(self, idx):
-		return self.eNBLogFiles[idx]
-
-	def GeteNBmbmsEnable(self, idx):
-		return self.eNBmbmsEnables[idx]
-
-	def SeteNB1IPAddress(self,enb1ip):
-		self.eNB1IPAddress = enb1ip
-	def GeteNB1IPAddress(self):
-		return self.eNB1IPAddress
-	def SeteNB1UserName(self, enb1usr):
-		self.eNB1UserName = enb1usr
-	def GeteNB1UserName(self):
-		return self.eNB1UserName
-	def SeteNB1Password(self, enb1pw):
-		self.eNB1Password = enb1pw
-	def GeteNB1Password(self):
-		return self.eNB1Password
-	def SeteNB1SourceCodePath(self, enb1codepath):
-		self.eNB1SourceCodePath = enb1codepath
-	def GeteNB1SourceCodePath(self):
-		return self.eNB1SourceCodePath
 
-	def SeteNB2IPAddress(self, enb2ip):
-		self.eNB2IPAddress = enb2ip
-	def GeteNB2IPAddress(self):
-		return self.eNB2IPAddress
-	def SeteNB2UserName(self, enb2usr):
-		self.eNB2UserName = enb2usr
-	def GeteNB2UserName(self):
-		return self.eNB2UserName
-	def SeteNB2Password(self, enb2pw):
-		self.eNB2Password = enb2pw
-	def GeteNB2Password(self):
-		return self.eNB2Password
-	def SeteNB2SourceCodePath(self, enb2codepath):
-		self.eNB2SourceCodePath = enb2codepath
-	def GeteNB2SourceCodePath(self):
-		return self.eNB2SourceCodePath
-
-	def SetprematureExit(self, premex):
-		self.prematureExit = premex
-	def GetprematureExit(self):
-		return self.prematureExit
 
 #-----------------------------------------------------------
 # RAN management functions
@@ -254,17 +121,23 @@ class RANManagement():
 			sys.exit('Insufficient Parameter')
 		mySSH = SSH.SSHConnection()
 		mySSH.open(lIpAddr, lUserName, lPassWord)
-		# Check if we build an 5G-NR gNB or an LTE eNB
-		result = re.search('--gNB', self.Build_eNB_args)
+		
+		# Check if we build an 5G-NR gNB or an LTE eNB or an OCP eNB
+		result = re.search('--eNBocp', self.Build_eNB_args)
 		if result is not None:
-			self.air_interface = 'nr'
-		else:
-			self.air_interface = 'lte'
+			self.air_interface[self.eNB_instance] = 'ocp-enb'
+		else:	
+			result = re.search('--gNB', self.Build_eNB_args)
+			if result is not None:
+				self.air_interface[self.eNB_instance] = 'nr-softmodem'
+			else:
+				self.air_interface[self.eNB_instance] = 'lte-softmodem'
+				
 		# Worakround for some servers, we need to erase completely the workspace
 		if self.Build_eNB_forced_workspace_cleanup:
 			mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15)
 		if self.htmlObj is not None:
-			self.testCase_id = self.htmlObj.GettestCase_id()
+			self.testCase_id = self.htmlObj.testCase_id
 		else:
 			self.testCase_id = '000000'
 		# on RedHat/CentOS .git extension is mandatory
@@ -332,7 +205,8 @@ class RANManagement():
 		if self.backgroundBuild:
 			mySSH.command('echo "./build_oai ' + self.Build_eNB_args + '" > ./my-lte-softmodem-build.sh', '\$', 5)
 			mySSH.command('chmod 775 ./my-lte-softmodem-build.sh', '\$', 5)
-			mySSH.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=build_enb_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/compile_oai_enb.log ./my-lte-softmodem-build.sh', '\$', 5)
+			mySSH.command('echo ' + lPassWord + ' | sudo -S ls', '\$', 5)
+			mySSH.command('echo $USER; nohup sudo -E ./my-lte-softmodem-build.sh' + ' > ' + lSourcePath + '/cmake_targets/compile_oai_enb.log ' + ' 2>&1 &', lUserName, 5)
 			mySSH.close()
 			if self.htmlObj is not None:
 				self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK)
@@ -378,21 +252,21 @@ class RANManagement():
 
 	def checkBuildeNB(self, lIpAddr, lUserName, lPassWord, lSourcePath, testcaseId):
 		if self.htmlObj is not None:
-			self.htmlObj.SettestCase_id(testcaseId)
+			self.htmlObj.testCase_id=testcaseId
+
 		mySSH = SSH.SSHConnection()
 		mySSH.open(lIpAddr, lUserName, lPassWord)
 		mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 3)
 		mySSH.command('ls ran_build/build', '\$', 3)
 		mySSH.command('ls ran_build/build', '\$', 3)
-		if self.air_interface == 'nr':
-			nodeB_prefix = 'g'
-		else:
-			nodeB_prefix = 'e'
-		buildStatus = True
-		result = re.search(self.air_interface + '-softmodem', mySSH.getBefore())
+
+		#check if we have the build corresponding to the air interface keywords (nr-softmode, lte-softmodem, ocp-enb)
+		logging.info('CHECK Build with IP='+lIpAddr+' SourcePath='+lSourcePath)
+		result = re.search(self.air_interface[self.eNB_instance], mySSH.getBefore())
 		if result is None:
-			buildStatus = False
+			buildStatus = False #if not, build failed
 		else:
+			buildStatus = True 
 			# Generating a BUILD INFO file
 			mySSH.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2)
 			mySSH.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2)
@@ -404,6 +278,8 @@ class RANManagement():
 					mySSH.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2)
 			else:
 				mySSH.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2)
+				
+				
 		mySSH.command('mkdir -p build_log_' + testcaseId, '\$', 5)
 		mySSH.command('mv log/* ' + 'build_log_' + testcaseId, '\$', 5)
 		mySSH.command('mv compile_oai_enb.log ' + 'build_log_' + testcaseId, '\$', 5)
@@ -420,18 +296,20 @@ class RANManagement():
 				os.remove('./tmp_build' + testcaseId + '.zip')
 				mySSH.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
 				mySSH.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5)
-				mySSH.command('unzip -qq -DD tmp_build' + testcaseId + '.zip', '\$', 5)
+				#-qq quiet / -u update orcreate files
+				mySSH.command('unzip -u -qq -DD tmp_build' + testcaseId + '.zip', '\$', 5)
 				mySSH.command('rm -f tmp_build' + testcaseId + '.zip', '\$', 5)
 				mySSH.close()
 		else:
 			mySSH.close()
 
+		#generate logging info depending on buildStatus and air interface
 		if buildStatus:
-			logging.info('\u001B[1m Building OAI ' + nodeB_prefix + 'NB Pass\u001B[0m')
+			logging.info('\u001B[1m Building OAI ' + self.air_interface[self.eNB_instance] + ' Pass\u001B[0m')
 			if self.htmlObj is not None:
-				self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK)
+				self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK)		
 		else:
-			logging.error('\u001B[1m Building OAI ' + nodeB_prefix + 'NB Failed\u001B[0m')
+			logging.error('\u001B[1m Building OAI ' + self.air_interface[self.eNB_instance] + ' Failed\u001B[0m')
 			if self.htmlObj is not None:
 				self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'KO', CONST.ALL_PROCESSES_OK)
 				self.htmlObj.CreateHtmlTabFooter(False)
@@ -458,22 +336,22 @@ class RANManagement():
 			sys.exit('Insufficient Parameter')
 
 		if self.htmlObj is not None:
-			self.testCase_id = self.htmlObj.GettestCase_id()
+			self.testCase_id = self.htmlObj.testCase_id
 		else:
 			self.testCase_id = '000000'
 		mySSH = SSH.SSHConnection()
 		
 		if (self.pStatus < 0):
 			if self.htmlObj is not None:
-				self.htmlObj.CreateHtmlTestRow(self.Initialize_eNB_args, 'KO', self.pStatus)
+				self.htmlObj.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' ' + self.Initialize_eNB_args, 'KO', self.pStatus)
 				self.htmlObj.CreateHtmlTabFooter(False)
 			sys.exit(1)
 		# If tracer options is on, running tshark on EPC side and capture traffic b/ EPC and eNB
 		result = re.search('T_stdout', str(self.Initialize_eNB_args))
 		if (result is not None) and (self.epcObj is not None):
-			localEpcIpAddr = self.epcObj.GetIPAddress()
-			localEpcUserName = self.epcObj.GetUserName()
-			localEpcPassword = self.epcObj.GetPassword()
+			localEpcIpAddr = self.epcObj.IPAddress
+			localEpcUserName = self.epcObj.UserName
+			localEpcPassword = self.epcObj.Password
 			mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword)
 			mySSH.command('ip addr show | awk -f /tmp/active_net_interfaces.awk | egrep -v "lo|tun"', '\$', 5)
 			result = re.search('interfaceToUse=(?P<eth_interface>[a-zA-Z0-9\-\_]+)done', mySSH.getBefore())
@@ -522,12 +400,14 @@ class RANManagement():
 		# Make a copy and adapt to EPC / eNB IP addresses
 		mySSH.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5)
 		if self.epcObj is not None:
-			localMmeIpAddr = self.epcObj.GetMmeIPAddress()
+			localMmeIpAddr = self.epcObj.MmeIPAddress
 			mySSH.command('sed -i -e \'s/CI_MME_IP_ADDR/' + localMmeIpAddr + '/\' ' + ci_full_config_file, '\$', 2);
 		mySSH.command('sed -i -e \'s/CI_ENB_IP_ADDR/' + lIpAddr + '/\' ' + ci_full_config_file, '\$', 2);
+		mySSH.command('sed -i -e \'s/CI_GNB_IP_ADDR/' + lIpAddr + '/\' ' + ci_full_config_file, '\$', 2);
 		mySSH.command('sed -i -e \'s/CI_RCC_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2);
 		mySSH.command('sed -i -e \'s/CI_RRU1_IP_ADDR/' + self.eNB1IPAddress + '/\' ' + ci_full_config_file, '\$', 2);
 		mySSH.command('sed -i -e \'s/CI_RRU2_IP_ADDR/' + self.eNB2IPAddress + '/\' ' + ci_full_config_file, '\$', 2);
+		mySSH.command('sed -i -e \'s/CI_FR1_CTL_ENB_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2);
 		if self.flexranCtrlInstalled and self.flexranCtrlStarted:
 			mySSH.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED        = "yes";/\' ' + ci_full_config_file, '\$', 2);
 		else:
@@ -549,15 +429,11 @@ class RANManagement():
 		if self.air_interface == 'nr':
 			mySSH.command('if [ -e rbconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm rbconfig.raw; fi', '\$', 5)
 			mySSH.command('if [ -e reconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm reconfig.raw; fi', '\$', 5)
-		mySSH.command('echo "ulimit -c unlimited && ./ran_build/build/' + self.air_interface + '-softmodem -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
+		# NOTE: WE SHALL do a check if the executable is present (in case build went wrong)
+		mySSH.command('echo "ulimit -c unlimited && ./ran_build/build/' + self.air_interface[self.eNB_instance] + ' -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
 		mySSH.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
 		mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5)
-		mySSH.command('hostnamectl','\$', 5)
-		result = re.search('CentOS Linux 7', mySSH.getBefore())
-		if result is not None:
-			mySSH.command('echo $USER; nohup sudo ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log 2>&1 &', lUserName, 10)
-		else:
-			mySSH.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
+		mySSH.command('echo $USER; nohup sudo -E ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log 2>&1 &', lUserName, 10)
 		self.eNBLogFiles[int(self.eNB_instance)] = 'enb_' + self.testCase_id + '.log'
 		if extra_options != '':
 			self.eNBOptions[int(self.eNB_instance)] = extra_options
@@ -574,15 +450,15 @@ class RANManagement():
 					mySSH.command('killall --signal SIGKILL record', '\$', 5)
 				mySSH.close()
 				doLoop = False
-				logging.error('\u001B[1;37;41m eNB logging system did not show got sync! \u001B[0m')
+				logging.error('\u001B[1;37;41m eNB/gNB/ocp-eNB logging system did not show got sync! \u001B[0m')
 				if self.htmlObj is not None:
-					self.htmlObj.CreateHtmlTestRow('-O ' + config_file + extra_options, 'KO', CONST.ALL_PROCESSES_OK)
+					self.htmlObj.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' -O ' + config_file + extra_options, 'KO', CONST.ALL_PROCESSES_OK)
 				# In case of T tracer recording, we need to kill tshark on EPC side
 				result = re.search('T_stdout', str(self.Initialize_eNB_args))
 				if (result is not None) and (self.epcObj is not None):
-					localEpcIpAddr = self.epcObj.GetIPAddress()
-					localEpcUserName = self.epcObj.GetUserName()
-					localEpcPassword = self.epcObj.GetPassword()
+					localEpcIpAddr = self.epcObj.IPAddress
+					localEpcUserName = self.epcObj.UserName
+					localEpcPassword = self.epcObj.Password
 					mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword)
 					logging.debug('\u001B[1m Stopping tshark \u001B[0m')
 					mySSH.command('echo ' + localEpcPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5)
@@ -634,8 +510,8 @@ class RANManagement():
 
 		mySSH.close()
 		if self.htmlObj is not None:
-			self.htmlObj.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', CONST.ALL_PROCESSES_OK)
-		logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m')
+			self.htmlObj.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' -O ' + config_file + extra_options, 'OK', CONST.ALL_PROCESSES_OK)
+		logging.debug('\u001B[1m Initialize eNB/gNB/ocp-eNB Completed\u001B[0m')
 
 	def CheckeNBProcess(self, status_queue):
 		try:
@@ -658,8 +534,8 @@ class RANManagement():
 				lPassWord = self.eNBPassword
 			mySSH = SSH.SSHConnection()
 			mySSH.open(lIpAddr, lUserName, lPassWord)
-			mySSH.command('stdbuf -o0 ps -aux | grep --color=never ' + self.air_interface + '-softmodem | grep -v grep', '\$', 5)
-			result = re.search(self.air_interface + '-softmodem', mySSH.getBefore())
+			mySSH.command('stdbuf -o0 ps -aux | grep --color=never ' + self.air_interface[self.eNB_instance] + ' | grep -v grep', '\$', 5)
+			result = re.search(self.air_interface[self.eNB_instance], mySSH.getBefore())
 			if result is None:
 				logging.debug('\u001B[1;37;41m eNB Process Not Found! \u001B[0m')
 				status_queue.put(CONST.ENB_PROCESS_FAILED)
@@ -691,29 +567,28 @@ class RANManagement():
 		mySSH = SSH.SSHConnection()
 		mySSH.open(lIpAddr, lUserName, lPassWord)
 		mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5)
-		if self.air_interface == 'lte':
+		if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'):
 			nodeB_prefix = 'e'
 		else:
 			nodeB_prefix = 'g'
-		mySSH.command('stdbuf -o0  ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5)
-		result = re.search('-softmodem', mySSH.getBefore())
+		mySSH.command('stdbuf -o0  ps -aux | grep --color=never -e softmodem -e ocp-enb | grep -v grep', '\$', 5)
+		result = re.search('(-softmodem|ocp)', mySSH.getBefore())
 		if result is not None:
-			mySSH.command('echo ' + lPassWord + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5)
-			mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT -r .*-softmodem || true', '\$', 5)
+			mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT -r .*-softmodem ocp-enb || true', '\$', 5)
 			time.sleep(10)
-			mySSH.command('stdbuf -o0  ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5)
-			result = re.search('-softmodem', mySSH.getBefore())
+			mySSH.command('stdbuf -o0  ps -aux | grep --color=never -e softmodem -e ocp-enb | grep -v grep', '\$', 5)
+			result = re.search('(-softmodem|ocp)', mySSH.getBefore())
 			if result is not None:
-				mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL -r .*-softmodem || true', '\$', 5)
+				mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL -r .*-softmodem ocp-enb || true', '\$', 5)
 				time.sleep(5)
 		mySSH.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
 		mySSH.close()
 		# If tracer options is on, stopping tshark on EPC side
 		result = re.search('T_stdout', str(self.Initialize_eNB_args))
 		if (result is not None) and (self.epcObj is not None):
-			localEpcIpAddr = self.epcObj.GetIPAddress()
-			localEpcUserName = self.epcObj.GetUserName()
-			localEpcPassword = self.epcObj.GetPassword()
+			localEpcIpAddr = self.epcObj.IPAddress
+			localEpcUserName = self.epcObj.UserName
+			localEpcPassword = self.epcObj.Password
 			mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword)
 			logging.debug('\u001B[1m Stopping tshark \u001B[0m')
 			mySSH.command('echo ' + localEpcPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5)
@@ -752,7 +627,7 @@ class RANManagement():
 				if (copyin_res == -1):
 					logging.debug('\u001B[1;37;41m Could not copy ' + nodeB_prefix + 'NB logfile to analyze it! \u001B[0m')
 					if self.htmlObj is not None:
-						self.htmlObj.SetHmleNBFailureMsg('Could not copy ' + nodeB_prefix + 'NB logfile to analyze it!')
+						self.htmlObj.htmleNBFailureMsg='Could not copy ' + nodeB_prefix + 'NB logfile to analyze it!'
 						self.htmlObj.CreateHtmlTestRow('N/A', 'KO', CONST.ENB_PROCESS_NOLOGFILE_TO_ANALYZE)
 					self.eNBmbmsEnables[int(self.eNB_instance)] = False
 					return
@@ -823,7 +698,30 @@ class RANManagement():
 		X2HO_inNbProcedures = 0
 		X2HO_outNbProcedures = 0
 		global_status = CONST.ALL_PROCESSES_OK
+		# Runtime statistics
+		runTime = ''
+		userTime = ''
+		systemTime = ''
+		maxPhyMemUsage = ''
+		nbContextSwitches = ''
 		for line in enb_log_file.readlines():
+			# Runtime statistics
+			result = re.search('Run time:' ,str(line))
+			if result is not None:
+				runTime = str(line).strip()
+			if runTime != '':
+				result = re.search('Time executing user inst', str(line))
+				if result is not None:
+					userTime = 'to be decoded - 1'
+				result = re.search('Time executing system inst', str(line))
+				if result is not None:
+					systemTime = 'to be decoded - 2'
+				result = re.search('Max. Phy. memory usage:', str(line))
+				if result is not None:
+					maxPhyMemUsage = 'to be decoded - 3'
+				result = re.search('Number of context switch.*process origin', str(line))
+				if result is not None:
+					nbContextSwitches = 'to be decoded - 4'
 			if X2HO_state == CONST.X2_HO_REQ_STATE__IDLE:
 				result = re.search('target eNB Receives X2 HO Req X2AP_HANDOVER_REQ', str(line))
 				if result is not None:
@@ -896,8 +794,7 @@ class RANManagement():
 			if result is not None:
 				rrcSetupComplete += 1
 			result = re.search('Generate LTE_RRCConnectionRelease|Generate RRCConnectionRelease', str(line))
-			if result is not None:
-				rrcReleaseRequest += 1
+			if result is not None:				rrcReleaseRequest += 1
 			result = re.search('Generate LTE_RRCConnectionReconfiguration', str(line))
 			if result is not None:
 				rrcReconfigRequest += 1
@@ -955,11 +852,11 @@ class RANManagement():
 					mbmsRequestMsg += 1
 		enb_log_file.close()
 		logging.debug('   File analysis completed')
-		if self.air_interface == 'lte':
+		if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'):
 			nodeB_prefix = 'e'
 		else:
 			nodeB_prefix = 'g'
-		if self.air_interface == 'nr':
+		if self.air_interface[self.eNB_instance] == 'nr-softmodem':
 			if ulschReceiveOK > 0:
 				statMsg = nodeB_prefix + 'NB showed ' + str(ulschReceiveOK) + ' "ULSCH received ok" message(s)'
 				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
@@ -1080,5 +977,12 @@ class RANManagement():
 			htmleNBFailureMsg += rlcMsg + '\n'
 			global_status = CONST.ENB_PROCESS_REALTIME_ISSUE
 		if self.htmlObj is not None:
-			self.htmlObj.SetHmleNBFailureMsg(htmleNBFailureMsg)
+			self.htmlObj.htmleNBFailureMsg=htmleNBFailureMsg
+		# Runtime statistics
+		if runTime != '':
+			logging.debug(runTime)
+			logging.debug('Time executing user inst   : ' + userTime)
+			logging.debug('Time executing system inst : ' + systemTime)
+			logging.debug('Max Physical Memory Usage  : ' + maxPhyMemUsage)
+			logging.debug('Nb Context Switches        : ' + nbContextSwitches)
 		return global_status
diff --git a/ci-scripts/sshconnection.py b/ci-scripts/sshconnection.py
index ba0f900f2940482589e3e9711c942031af88cd9a..ed0cf5379a18aa121e0a2cd373a9faf26518366e 100644
--- a/ci-scripts/sshconnection.py
+++ b/ci-scripts/sshconnection.py
@@ -101,6 +101,18 @@ class SSHConnection():
 		else:
 			sys.exit('SSH Connection Failed')
 
+
+
+
+	def cde_check_value(self, commandline, expected, timeout):
+		logging.debug(commandline)
+		self.ssh.timeout = timeout
+		self.ssh.sendline(commandline)
+		expected.append(pexpect.EOF)
+		expected.append(pexpect.TIMEOUT)
+		self.sshresponse = self.ssh.expect(expected)
+		return self.sshresponse
+
 	def command(self, commandline, expectedline, timeout):
 		logging.debug(commandline)
 		self.ssh.timeout = timeout
diff --git a/ci-scripts/xml_class_list.yml b/ci-scripts/xml_class_list.yml
new file mode 100755
index 0000000000000000000000000000000000000000..56890c1fc682b926ee834a0ff5a3d827776a2b46
--- /dev/null
+++ b/ci-scripts/xml_class_list.yml
@@ -0,0 +1,35 @@
+  - COTS_UE_Airplane
+  - Build_PhySim
+  - Run_PhySim
+  - Build_eNB
+  - WaitEndBuild_eNB
+  - Initialize_eNB
+  - Terminate_eNB
+  - Initialize_UE
+  - Terminate_UE
+  - Attach_UE
+  - Detach_UE
+  - Build_OAI_UE
+  - Initialize_OAI_UE
+  - Terminate_OAI_UE
+  - DataDisable_UE
+  - DataEnable_
+  - CheckStatusUE
+  - Ping
+  - Iperf
+  - Reboot_UE
+  - Initialize_FlexranCtrl
+  - Terminate_FlexranCtrl
+  - Initialize_HSS
+  - Terminate_HSS
+  - Initialize_MME
+  - Terminate_MME
+  - Initialize_SPGW
+  - Terminate_SPGW
+  - Initialize_CatM_module
+  - Terminate_CatM_module
+  - Attach_CatM_module
+  - Detach_CatM_module
+  - Ping_CatM_module
+  - IdleSleep
+  - Perform_X2_Handover
diff --git a/ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a4caa77075979939cdbe7530caa1f8a399129e57
--- /dev/null
+++ b/ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml
@@ -0,0 +1,147 @@
+<!--
+
+ Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The OpenAirInterface Software Alliance licenses this file to You under
+ the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.openairinterface.org/?page_id=698
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ For more information about the OpenAirInterface (OAI) Software Alliance:
+      contact@openairinterface.org
+
+-->
+<testCaseList>
+	<htmlTabRef>test-05-tm1</htmlTabRef>
+	<htmlTabName>Test-05MHz-TM1</htmlTabName>
+	<htmlTabIcon>tasks</htmlTabIcon>
+	<repeatCount>4</repeatCount>
+	<TestCaseRequestedList>
+ 030201
+ 040101
+ 030101 040301 040501 040603 040604 040605 040606 040607 040641 040642 040643 040644 040401 040201 030201
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="030101">
+		<class>Initialize_eNB</class>
+		<desc>Initialize OCP-eNB (FDD/Band7/5MHz)</desc>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf</Initialize_eNB_args>
+		<air_interface>ocp</air_interface>
+	</testCase>
+
+	<testCase id="030201">
+		<class>Terminate_eNB</class>
+		<desc>Terminate OCP-eNB</desc>
+		<air_interface>ocp</air_interface>
+	</testCase>
+
+	<testCase id="040101">
+		<class>Initialize_UE</class>
+		<desc>Initialize UE</desc>
+	</testCase>
+
+	<testCase id="040201">
+		<class>Terminate_UE</class>
+		<desc>Terminate UE</desc>
+	</testCase>
+
+	<testCase id="040301">
+		<class>Attach_UE</class>
+		<desc>Attach UE</desc>
+	</testCase>
+
+	<testCase id="040401">
+		<class>Detach_UE</class>
+		<desc>Detach UE</desc>
+	</testCase>
+
+	<testCase id="040501">
+		<class>Ping</class>
+		<desc>ping (5MHz - 20 sec)</desc>
+		<ping_args>-c 20</ping_args>
+		<ping_packetloss_threshold>5</ping_packetloss_threshold>
+	</testCase>
+
+	<testCase id="040603">
+		<class>Iperf</class>
+		<desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile)</desc>
+		<iperf_args>-u -b 15M -t 30 -i 1</iperf_args>
+		<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
+		<iperf_profile>balanced</iperf_profile>
+	</testCase>
+
+	<testCase id="040604">
+		<class>Iperf</class>
+		<desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile)</desc>
+		<iperf_args>-u -b 15M -t 30 -i 1</iperf_args>
+		<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
+		<iperf_profile>single-ue</iperf_profile>
+	</testCase>
+
+	<testCase id="040605">
+		<class>Iperf</class>
+		<desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(unbalanced profile)</desc>
+		<iperf_args>-u -b 15M -t 30 -i 1</iperf_args>
+		<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
+		<iperf_profile>unbalanced</iperf_profile>
+	</testCase>
+
+	<testCase id="040606">
+		<class>Iperf</class>
+		<desc>iperf (5MHz - DL/TCP)(30 sec)(single-ue profile)</desc>
+		<iperf_args>-t 30 -i 1 -fm</iperf_args>
+		<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
+		<iperf_profile>single-ue</iperf_profile>
+	</testCase>
+
+	<testCase id="040607">
+		<class>Iperf</class>
+		<desc>iperf (5MHz - DL/TCP)(30 sec)(balanced profile)</desc>
+		<iperf_args>-t 30 -i 1 -fm</iperf_args>
+		<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
+		<iperf_profile>balanced</iperf_profile>
+	</testCase>
+
+	<testCase id="040641">
+		<class>Iperf</class>
+		<desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile)</desc>
+		<iperf_args>-u -b 9M -t 30 -i 1 -R</iperf_args>
+		<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
+		<iperf_profile>balanced</iperf_profile>
+	</testCase>
+
+	<testCase id="040642">
+		<class>Iperf</class>
+		<desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile)</desc>
+		<iperf_args>-u -b 9M -t 30 -i 1 -R</iperf_args>
+		<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
+		<iperf_profile>single-ue</iperf_profile>
+	</testCase>
+
+	<testCase id="040643">
+		<class>Iperf</class>
+		<desc>iperf (5MHz - UL/TCP)(30 sec)(single-ue profile)</desc>
+		<iperf_args>-t 30 -i 1 -fm -R</iperf_args>
+		<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
+		<iperf_profile>single-ue</iperf_profile>
+	</testCase>
+
+	<testCase id="040644">
+		<class>Iperf</class>
+		<desc>iperf (5MHz - UL/TCP)(30 sec)(balanced profile)</desc>
+		<iperf_args>-t 30 -i 1 -fm -R</iperf_args>
+		<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
+		<iperf_profile>balanced</iperf_profile>
+	</testCase>
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/enb_ocp_usrp210_build.xml b/ci-scripts/xml_files/enb_ocp_usrp210_build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..33a0fc205e0855de99602abc4f7394e89ad98963
--- /dev/null
+++ b/ci-scripts/xml_files/enb_ocp_usrp210_build.xml
@@ -0,0 +1,38 @@
+<!--
+
+ Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The OpenAirInterface Software Alliance licenses this file to You under
+ the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.openairinterface.org/?page_id=698
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ For more information about the OpenAirInterface (OAI) Software Alliance:
+      contact@openairinterface.org
+
+-->
+<testCaseList>
+	<htmlTabRef>build-tab</htmlTabRef>
+	<htmlTabName>Build</htmlTabName>
+	<htmlTabIcon>wrench</htmlTabIcon>
+	<TestCaseRequestedList>
+ 010101
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="010101">
+		<class>Build_eNB</class>
+		<desc>Build eNB OCP (USRP)</desc>
+		<Build_eNB_args>-w USRP -c --eNBocp --ninja</Build_eNB_args>
+	</testCase>
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/fr1_multi_node_build.xml b/ci-scripts/xml_files/fr1_multi_node_build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7b4eacef3a3d091e7397bfc89a7f8422c459998c
--- /dev/null
+++ b/ci-scripts/xml_files/fr1_multi_node_build.xml
@@ -0,0 +1,66 @@
+<!--
+
+ Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The OpenAirInterface Software Alliance licenses this file to You under
+ the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.openairinterface.org/?page_id=698
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ For more information about the OpenAirInterface (OAI) Software Alliance:
+      contact@openairinterface.org
+
+-->
+<testCaseList>
+	<htmlTabRef>build-tab</htmlTabRef>
+	<htmlTabName>Build</htmlTabName>
+	<htmlTabIcon>wrench</htmlTabIcon>
+	<TestCaseRequestedList>
+ 000001 000002
+ 000003 000004
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="000001">
+		<class>Build_eNB</class>
+		<desc>Build eNB</desc>
+		<Build_eNB_args>-w USRP -c --eNB --ninja</Build_eNB_args>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+		<backgroundBuild>True</backgroundBuild>
+	</testCase>
+
+	<testCase id="000004">
+		<class>WaitEndBuild_eNB</class>
+		<desc>Wait for end of Build eNB</desc>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+	</testCase>
+
+	<testCase id="000002">
+		<class>Build_eNB</class>
+		<desc>Build gNB</desc>
+		<Build_eNB_args>-w USRP -c --gNB --ninja</Build_eNB_args>
+		<eNB_instance>1</eNB_instance>
+		<eNB_serverId>1</eNB_serverId>
+		<backgroundBuild>True</backgroundBuild>
+	</testCase>
+
+	<testCase id="000003">
+		<class>WaitEndBuild_eNB</class>
+		<desc>Wait for end of Build gNB</desc>
+		<eNB_instance>1</eNB_instance>
+		<eNB_serverId>1</eNB_serverId>
+	</testCase>
+
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/fr1_multi_node_terminate.xml b/ci-scripts/xml_files/fr1_multi_node_terminate.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cbaaf8ba9975a8e464424e0ff258e64a5b3aabac
--- /dev/null
+++ b/ci-scripts/xml_files/fr1_multi_node_terminate.xml
@@ -0,0 +1,50 @@
+<!--
+
+ Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The OpenAirInterface Software Alliance licenses this file to You under
+ the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.openairinterface.org/?page_id=698
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ For more information about the OpenAirInterface (OAI) Software Alliance:
+      contact@openairinterface.org
+
+-->
+<testCaseList>
+	<htmlTabRef>test-fr1-tm1</htmlTabRef>
+	<htmlTabName>Test-FR1-TM1</htmlTabName>
+	<htmlTabIcon>tasks</htmlTabIcon>
+	<repeatCount>1</repeatCount>
+	<TestCaseRequestedList>
+ 070001
+ 070000
+	</TestCaseRequestedList>
+	<TestCaseExclusionList>
+	</TestCaseExclusionList>
+
+	<testCase id="070000">
+		<class>Terminate_eNB</class>
+		<desc>Terminate eNB</desc>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+	</testCase>
+
+	<testCase id="070001">
+		<class>Terminate_eNB</class>
+		<desc>Terminate gNB</desc>
+		<eNB_instance>1</eNB_instance>
+		<eNB_serverId>1</eNB_serverId>
+	</testCase>
+
+</testCaseList>
+
diff --git a/ci-scripts/xml_files/fr1_multi_node_test.xml b/ci-scripts/xml_files/fr1_multi_node_test.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8c56f0bcec9354394dc622d86675e30ff1281dff
--- /dev/null
+++ b/ci-scripts/xml_files/fr1_multi_node_test.xml
@@ -0,0 +1,77 @@
+<!--
+
+ Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The OpenAirInterface Software Alliance licenses this file to You under
+ the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.openairinterface.org/?page_id=698
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ For more information about the OpenAirInterface (OAI) Software Alliance:
+      contact@openairinterface.org
+
+-->
+<testCaseList>
+	<htmlTabRef>test-fr1-tm1</htmlTabRef>
+	<htmlTabName>Test-FR1-TM1</htmlTabName>
+	<htmlTabIcon>tasks</htmlTabIcon>
+	<repeatCount>1</repeatCount>
+	<TestCaseRequestedList>
+ 030000
+ 040000
+ 000001
+ 070001
+ 070000
+	</TestCaseRequestedList>
+	<TestCaseExclusionList>
+	</TestCaseExclusionList>
+
+	<testCase id="030000">
+		<class>Initialize_eNB</class>
+		<desc>Initialize eNB</desc>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf</Initialize_eNB_args>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+		<air_interface>lte</air_interface>
+	</testCase>
+
+	<testCase id="040000">
+		<class>Initialize_eNB</class>
+		<desc>Initialize gNB (3/4 sampling rate)</desc>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf -E</Initialize_eNB_args>
+		<eNB_instance>1</eNB_instance>
+		<eNB_serverId>1</eNB_serverId>
+		<air_interface>nr</air_interface>
+	</testCase>
+
+	<testCase id="000001">
+		<class>IdleSleep</class>
+		<desc>Sleep</desc>
+		<idle_sleep_time_in_sec>30</idle_sleep_time_in_sec>
+	</testCase>
+
+	<testCase id="070000">
+		<class>Terminate_eNB</class>
+		<desc>Terminate eNB</desc>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+	</testCase>
+
+	<testCase id="070001">
+		<class>Terminate_eNB</class>
+		<desc>Terminate gNB</desc>
+		<eNB_instance>1</eNB_instance>
+		<eNB_serverId>1</eNB_serverId>
+	</testCase>
+
+</testCaseList>
+
diff --git a/ci-scripts/xml_files/fr1_toggle_cots_ue.xml b/ci-scripts/xml_files/fr1_toggle_cots_ue.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b2267efc77dcc514bcf07eda0c2223be3ed5b46a
--- /dev/null
+++ b/ci-scripts/xml_files/fr1_toggle_cots_ue.xml
@@ -0,0 +1,39 @@
+<!--
+
+ Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The OpenAirInterface Software Alliance licenses this file to You under
+ the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.openairinterface.org/?page_id=698
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ For more information about the OpenAirInterface (OAI) Software Alliance:
+      contact@openairinterface.org
+
+-->
+<testCaseList>
+	<htmlTabRef>test-airplane-mode</htmlTabRef>
+	<htmlTabName>AirplaneToggle</htmlTabName>
+	<htmlTabIcon>tasks</htmlTabIcon>
+	<TestCaseRequestedList>
+ 010000
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="010000">
+		<class>COTS_UE_Airplane</class>
+		<desc>Toggle COTS Airplane mode ON</desc>
+		<cots_ue_airplane_args>ON</cots_ue_airplane_args>
+	</testCase>
+
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/gnb_usrp_build.xml b/ci-scripts/xml_files/gnb_usrp_build.xml
index 97d6ef06f6221875c6b25809d19af7fddb345bf6..e2662180c5b8fee0c2974e703328a30673eb5193 100644
--- a/ci-scripts/xml_files/gnb_usrp_build.xml
+++ b/ci-scripts/xml_files/gnb_usrp_build.xml
@@ -34,7 +34,7 @@
 		<mode>TesteNB</mode>	
 		<class>Build_eNB</class>
 		<desc>Build gNB (USRP)</desc>
-		<Build_eNB_args>--gNB -w USRP</Build_eNB_args>
+		<Build_eNB_args>--gNB -w USRP --ninja</Build_eNB_args>
 		<forced_workspace_cleanup>True</forced_workspace_cleanup>
 	</testCase>
 
diff --git a/ci-scripts/xml_files/nr_ue_usrp_build.xml b/ci-scripts/xml_files/nr_ue_usrp_build.xml
index c3c842b85a9bb2974890cd9757de8ecb3a1172a4..bc04efdb4b8cd50ffd7905196f2f14b941db14ab 100644
--- a/ci-scripts/xml_files/nr_ue_usrp_build.xml
+++ b/ci-scripts/xml_files/nr_ue_usrp_build.xml
@@ -34,7 +34,7 @@
 		<mode>TestUE</mode>
 		<class>Build_OAI_UE</class>
 		<desc>Build NR UE (USRP)</desc>
-		<Build_OAI_UE_args>--nrUE -w USRP</Build_OAI_UE_args>
+		<Build_OAI_UE_args>--nrUE -w USRP --ninja</Build_OAI_UE_args>
 		<clean_repository>false</clean_repository>
 	</testCase>
 
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 0b6017274728e88d571bb32638ee4305a7355e3c..5db0b1f021e112115de3bda01a38eb22d71e60b8 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -27,6 +27,10 @@ cmake_minimum_required (VERSION 3.0)
 # Base directories, compatible with legacy OAI building #
 #########################################################
 set (OPENAIR_DIR     $ENV{OPENAIR_DIR})
+if("${OPENAIR_DIR}" STREQUAL "")
+  string(REGEX REPLACE "/cmake_targets.*$" "" OPENAIR_DIR ${CMAKE_CURRENT_BINARY_DIR})
+endif()
+
 set (NFAPI_DIR       ${OPENAIR_DIR}/nfapi/open-nFAPI)
 set (NFAPI_USER_DIR  ${OPENAIR_DIR}/nfapi/oai_integration)
 set (OPENAIR1_DIR    ${OPENAIR_DIR}/openair1)
@@ -2624,7 +2628,7 @@ add_executable(ocp-enb
   ${CONFIG_SOURCES}
   ${SHLIB_LOADER_SOURCES}
   )
-add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer)
+add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer coding params_libconfig rfsimulator)
 
 target_link_libraries (ocp-enb
   -Wl,--start-group
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index e0093c909c266609705021e32a99c934ebac8d88..90edcf83c0b239bc47b9c25d5c8d19aac6ecb4c0 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -96,7 +96,9 @@ Options
    enable cmake debugging messages
 --eNB
   Makes the LTE softmodem
---gNB
+--eNBocp
+  Makes the OCP LTE softmodem
+-gNB
   Makes the NR softmodem
 --nrUE
   Makes the NR UE softmodem
@@ -237,7 +239,11 @@ function main() {
             eNB=1
             echo_info "Will compile eNB"
             shift;;
-       --gNB)
+       --eNBocp)
+            eNBocp=1
+            echo_info "Will compile OCP eNB"
+            shift;;
+      --gNB)
             gNB=1
             NR="True"
             echo_info "Will compile gNB"
@@ -443,7 +449,7 @@ function main() {
   ########################################################
   # to be discussed
   
-  if [ "$eNB" = "1" -o "$gNB" = "1" ] ; then
+  if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$gNB" = "1" ] ; then
       if [ "$HW" = "None" -a  "$TP" = "None" ] ; then
 	      echo_info "No local radio head and no transport protocol selected"
       fi
@@ -574,7 +580,7 @@ function main() {
   config_libconfig_shlib=params_libconfig
   
   # first generate the CMakefile in the right directory
-  if [ "$eNB" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" -o "$HW" = "EXMIMO" ] ; then
+  if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" -o "$HW" = "EXMIMO" ] ; then
 
     # softmodem compilation
 
@@ -607,6 +613,9 @@ function main() {
     if [ "$eNB" = "1" ] ; then
       execlist="$execlist lte-softmodem"
     fi
+    if [ "$eNBocp" = "1" ] ; then
+      execlist="$execlist ocp-enb"
+    fi
     if [ "$gNB" = "1" ] ; then
       execlist="$execlist nr-softmodem"
     fi
@@ -822,7 +831,7 @@ function main() {
   ####################################################
   # Build RF device and transport protocol libraries #
   ####################################################
-  if [ "$eNB" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" -o "$HWLAT" = "1" ] ; then
+  if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" -o "$HWLAT" = "1" ] ; then
 
       # build RF device libraries
       if [ "$HW" != "None" ] ; then
diff --git a/doc/TESTING_GNB_W_COTS_UE.md b/doc/TESTING_GNB_W_COTS_UE.md
index e507050239767f9d1b602486b8214d5dcc676b20..a16b4dbe136034d7f7cc4ae33555016a4b448e0a 100644
--- a/doc/TESTING_GNB_W_COTS_UE.md
+++ b/doc/TESTING_GNB_W_COTS_UE.md
@@ -1,4 +1,5 @@
-STATUS 2020/06/26 : information is up to date, but under continuous improvement
+STATUS 2020/07/30 : under continuous improvement ; updated the configuration files links with CI approved reference files
+
 
 ## Table of Contents ##
 
@@ -78,16 +79,16 @@ https://github.com/OPENAIRINTERFACE/openair-epc-fed/blob/master-documentation/do
 Each component (EPC, eNB, gNB) has its own configuration file.  
 These config files are passed as arguments of the run command line, using the option -O \<conf file\>
 
-Some config examples can be found in the following folder:  
-https://gitlab.eurecom.fr/oai/openairinterface5g/-/tree/develop/targets/PROJECTS/GENERIC-LTE-EPC/CONF
+The **REFERENCE** files for eNB and gNB, **used by the CI**, can be found here:  
+[enb conf file](../ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf)
+[gnb conf file](../ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf)
 
-Also base config files can be found here:  
-[enb conf file](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/rh_doc_update_3/doc/testing_gnb_w_cots_ue_resources/enb.conf)  
-[gnb conf file](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/rh_doc_update_3/doc/testing_gnb_w_cots_ue_resources/gnb.conf)
+These files have to be updated manually to set the IP addresses and frequency.  
 
-TO DO : attach base confif files
 
-These files have to be updated manually to set the IP addresses and frequency.  
+**ATTENTION** : an **EXTERNAL** clock is used to sync the eNB and gNB,  
+whether the clock is internal or external is defined in the configuration files (!! details needed !!)   
+
 
 1- In the **eNB configuration file** :
 - look for MME IP address, and update the **ipv4 field** with the IP address of the **EPC** server
@@ -128,7 +129,7 @@ These files have to be updated manually to set the IP addresses and frequency.
                             }
                           );
 ```
-- look for X2 IP address, and update the **4 fields** with the IP address of the **eNB** server (notice : even if -in principle- S1 MME is not required for gNB setting)
+- look for X2 IP address, and update the **4 fields** with the IP address of the **eNB** server / **gNB** server as below  (notice : even if -in principle- S1 MME is not required for gNB setting)
 ```
 
     ///X2
@@ -146,11 +147,11 @@ These files have to be updated manually to set the IP addresses and frequency.
     {
 
         GNB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
-        GNB_IPV4_ADDRESS_FOR_S1_MME              = "**YOUR_ENB_IP_ADDR**";
+        GNB_IPV4_ADDRESS_FOR_S1_MME              = "**YOUR_GNB_IP_ADDR**";
         GNB_INTERFACE_NAME_FOR_S1U               = "eth0";
-        GNB_IPV4_ADDRESS_FOR_S1U                 = "**YOUR_ENB_IP_ADDR**";
+        GNB_IPV4_ADDRESS_FOR_S1U                 = "**YOUR_GNB_IP_ADDR**";
         GNB_PORT_FOR_S1U                         = 2152; # Spec 2152
-        GNB_IPV4_ADDRESS_FOR_X2C                 = "**YOUR_ENB_IP_ADDR**";
+        GNB_IPV4_ADDRESS_FOR_X2C                 = "**YOUR_GNB_IP_ADDR**";
         GNB_PORT_FOR_X2C                         = 36422; # Spec 36422
     };
 
@@ -215,26 +216,20 @@ Execute:
 
 ```
 
-For example:
-```
-~/openairinterface5g/cmake_targets/ran_build/build$ sudo ./lte-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf | tee mylogfile.log
-```
-
-
 
 - **gNB** (on the gNB host)
 
 
 Execute: 
 ```
-~/openairinterface5g/cmake_targets/ran_build/build$ sudo ./nr-softmodem -O **YOUR_GNB_CONF_FILE** | tee **YOUR_LOG_FILE**
+~/openairinterface5g/cmake_targets/ran_build/build$ sudo ./nr-softmodem -O **YOUR_GNB_CONF_FILE** -E | tee **YOUR_LOG_FILE**
 
 ```
 
-For example:
-```
-~/openairinterface5g/cmake_targets/ran_build/build$ sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf | tee mylogfile.log
-```
+**ATTENTION** : for the gNB execution,    
+The -E option is required to enable the tri-quarter sampling rate when using a B2xx serie USRP  
+The -E opton is not needed when using a a N300 USRP  
+
 
 
 ## Test Case
diff --git a/executables/main-fs6.c b/executables/main-fs6.c
index ffa44bd978758cc13923499970ff8743e938543f..d2d64d09593b9a27464d1dd232ecd9e2428f350a 100644
--- a/executables/main-fs6.c
+++ b/executables/main-fs6.c
@@ -401,7 +401,7 @@ void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_
   hULUE(newUDPheader)->O_ACK=eNB->ulsch[UE_id]->harq_processes[harq_pid]->O_ACK;
   memcpy(hULUE(newUDPheader)->o_ACK, eNB->ulsch[UE_id]->harq_processes[harq_pid]->o_ACK,
          sizeof(eNB->ulsch[UE_id]->harq_processes[harq_pid]->o_ACK));
-  hULUE(newUDPheader)->ta=lte_est_timing_advance_pusch(eNB, UE_id);
+  hULUE(newUDPheader)->ta=lte_est_timing_advance_pusch(&eNB->frame_parms, eNB->pusch_vars[UE_id]->drs_ch_estimates_time);
   hULUE(newUDPheader)->segment=segmentID;
   memcpy(hULUE(newUDPheader)->o, eNB->ulsch[UE_id]->harq_processes[harq_pid]->o,
          sizeof(eNB->ulsch[UE_id]->harq_processes[harq_pid]->o));
diff --git a/executables/main-ocp.c b/executables/main-ocp.c
index e4e42b4f23b069c053be31d02d5c4d6f289534e9..2d96d40c75e78717baa6f7d2c23fd5ad3bb9d9b7 100644
--- a/executables/main-ocp.c
+++ b/executables/main-ocp.c
@@ -1167,6 +1167,7 @@ int main ( int argc, char **argv ) {
   T_Config_Init();
 #endif
   configure_linux();
+  set_softmodem_sighandler();
   cpuf=get_cpu_freq_GHz();
   set_taus_seed (0);
 
diff --git a/executables/split_headers.h b/executables/split_headers.h
index 4e328f74c418c7f902014b99630dd4fbe2130e7a..985b1b7daebe98ecec8731fbef27d033cc57ef7d 100644
--- a/executables/split_headers.h
+++ b/executables/split_headers.h
@@ -28,6 +28,7 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include <openair1/PHY/defs_eNB.h>
+#include <common/utils/telnetsrv/telnetsrv_proccmd.h>
 
 #define CU_PORT "7878"
 #define DU_PORT "8787"
@@ -325,5 +326,6 @@ void fep_full(RU_t *ru, int subframe);
 void feptx_prec(RU_t *ru,int frame,int subframe);
 void feptx_ofdm(RU_t *ru, int frame, int subframe);
 void oai_subframe_ind(uint16_t sfn, uint16_t sf);
+void softmodem_printresources(int sig, telnet_printfunc_t pf);
 extern uint16_t sf_ahead;
 #endif
diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c
index 6a037b8ee3461f2f53b26ee52d3aa6d8294059e1..bd7727274705b92da83d6c99a00953eaddd4a011 100644
--- a/openair2/X2AP/x2ap_eNB.c
+++ b/openair2/X2AP/x2ap_eNB.c
@@ -116,7 +116,9 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
       /* some sanity check - to be refined at some point */
       if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
         X2AP_ERROR("x2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n");
-        abort();
+        // Allow for a gracious exit when we kill first the gNB, then the eNB
+        //abort();
+        return;
       }
 
       x2ap_enb_data_p->in_streams  = sctp_new_association_resp->in_streams;
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 4715a4e99561fd7af741bcf94133040898a5ce20..26f84e66c033bb0f89629d82a5fc180b85eeb969 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -556,6 +556,8 @@ int main ( int argc, char **argv )
 
   MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
   init_opt();
+  // to make a graceful exit when ctrl-c is pressed
+  set_softmodem_sighandler();
   check_clock();
 #ifndef PACKAGE_VERSION
 #  define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"