diff --git a/ci-scripts/cls_cots_ue.py b/ci-scripts/cls_cots_ue.py
index 6954aa392742f1ca77ee64d46e97b468a2614cff..bb17f426d7cffb077674f6a515ae39417b0a8b87 100644
--- a/ci-scripts/cls_cots_ue.py
+++ b/ci-scripts/cls_cots_ue.py
@@ -33,14 +33,17 @@ import logging
 import sshconnection
 #time.sleep
 import time
+#to load cots_ue dictionary
+import yaml
 
 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
+	def __init__(self,ADBIPAddr,ADBUserName,ADBPassWord):
+		self.cots_id = '' #cots id from yaml oppo, s10 etc...
+		self.ADBIPAddr = ADBIPAddr 
+		self.ADBUserName = ADBUserName
+		self.ADBPassWord = ADBPassWord
+		self.cots_run_mode = '' #on of off to toggle airplane mode on/off
+		self.__cots_cde_dict_file = 'cots_ue_ctl.yaml'
 		self.__SetAirplaneRetry = 3
 
 #-----------------$
@@ -49,39 +52,50 @@ class CotsUe:
 
 	def Check_Airplane(self):
 		mySSH = sshconnection.SSHConnection()
-		mySSH.open(self.UEIPAddr, self.UEUserName, self.UEPassWord)
+		mySSH.open(self.ADBIPAddr, self.ADBUserName, self.ADBPassWord)
 		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
+	def Set_Airplane(self, target_id, target_state_str):
+		#load cots commands dictionary
+		with open(self.__cots_cde_dict_file,'r') as file:
+			cots_ue_ctl = yaml.load(file,Loader=yaml.FullLoader)
+		#check if ue id is in the dictionary
+		if target_id in cots_ue_ctl:
+			mySSH = sshconnection.SSHConnection()
+			mySSH.open(self.ADBIPAddr, self.ADBUserName, self.ADBPassWord)
+			mySSH.command('sudo adb start-server','\$',5)
+			logging.info("Toggling COTS UE Airplane mode to : "+target_state_str)
+			#get current state
+			current_state = self.Check_Airplane()
+			if target_state_str.lower()=="on": 
+				target_state=1
+			else:
+				target_state=0
 			if current_state != target_state:
-				logging.error("ATTENTION : Could not toggle to : "+target_state_str)
-				logging.error("Current state is : "+ str(current_state))
+				#toggle state
+				retry = 0 
+				while (current_state!=target_state) and (retry < self.__SetAirplaneRetry):
+					#loop over the command list from dictionary for the selected ue, to switch to required state
+					for i in range (0,len(cots_ue_ctl[target_id])):
+						mySSH.command(cots_ue_ctl[target_id][i], '\$', 5)
+					time.sleep(1)
+					current_state = self.Check_Airplane()
+					retry+=1
+				#could not toggle despite the retry
+				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()
+		#ue id is NOT in the dictionary
 		else:
-			print("Airplane mode is already "+ target_state_str)
-		mySSH.command('sudo adb kill-server','$',5)
-		mySSH.close()
+			logging.error("COTS UE Id from XML could not be found in UE YAML dictionary " + self.__cots_cde_dict_file)
+			sys.exit("COTS UE Id from XML could not be found in UE YAML dictionary " + self.__cots_cde_dict_file)
 
 
 
diff --git a/ci-scripts/cots_ue_ctl.yaml b/ci-scripts/cots_ue_ctl.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..503a6d974b3ef6b1cb47d54aeb43890f19c4282d
--- /dev/null
+++ b/ci-scripts/cots_ue_ctl.yaml
@@ -0,0 +1,18 @@
+oppo:
+  - adb shell am start -a android.settings.AIRPLANE_MODE_SETTINGS
+  - adb shell input keyevent 20
+  - adb shell input tap 968 324
+s10:
+  - adb shell input keyevent KEYCODE_POWER
+  - adb shell input swipe 200 900 200 300
+  - adb shell am start -a android.settings.AIRPLANE_MODE_SETTINGS
+  - adb shell input tap 968 324
+s20:
+  - adb shell input keyevent KEYCODE_POWER
+  - adb shell input swipe 200 900 200 300
+  - adb shell am start -a android.settings.AIRPLANE_MODE_SETTINGS
+  - adb shell input tap 968 324
+xperia:
+  - tbd
+  - tbd
+  - tbd
diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index d37f205f4e6a11cb72ebacb3455613b52b21d2f9..ccb7419908d12b3dddb99a1cb84eb236343698db 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -3295,7 +3295,8 @@ def GetParametersFromXML(action):
 		ldpc.runargs = test.findtext('physim_run_args')
 		
 	if action == 'COTS_UE_Airplane':
-		COTS_UE.runargs = test.findtext('cots_ue_airplane_args')
+		COTS_UE.cots_id = test.findtext('cots_id')
+		COTS_UE.cots_run_mode = test.findtext('cots_run_mode')
 
 #check if given test is in list
 #it is in list if one of the strings in 'list' is at the beginning of 'test'
@@ -3323,11 +3324,15 @@ 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'
+elif (os.path.isfile('ci_scripts/xml_class_list.yml')):
+	xml_class_list_file='ci_scripts/xml_class_list.yml'
+else:
+	logging.error("XML action list yaml file cannot be found")
+	sys.exit("XML action list yaml file cannot be found")
+#file will be opened only if it exists
 with open(xml_class_list_file,'r') as file:
-    # The FullLoader parameter handles the conversion from YAML
-    # scalar values to Python the dictionary format
+    # The FullLoader parameter handles the conversion 
+    #from YAML scalar values to Python dictionary format
     xml_class_list = yaml.load(file,Loader=yaml.FullLoader)
 
 mode = ''
@@ -3375,8 +3380,9 @@ if py_param_file_present == True:
 #-----------------------------------------------------------
 # 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)
+#COTS_UE instanciation and ADB server init
+#ue id and ue mode are retrieved from xml
+COTS_UE=cls_cots_ue.CotsUe(CiTestObj.ADBIPAddress, CiTestObj.ADBUserName,CiTestObj.ADBPassword)
 
 
 #-----------------------------------------------------------
@@ -3689,7 +3695,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 				elif action == 'Run_PhySim':
 					HTML=ldpc.Run_PhySim(HTML,CONST,id)
 				elif action == 'COTS_UE_Airplane':
-					COTS_UE.Set_Airplane(COTS_UE.runargs)
+					#cots id and cots run mode were read from xml test file
+					COTS_UE.Set_Airplane(COTS_UE.cots_id, COTS_UE.cots_run_mode)
 				else:
 					sys.exit('Invalid class (action) from xml')
 		CiTestObj.FailReportCnt += 1
diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py
index 96f28e21fe3f58e19d56510c3fcac22645a2df05..c0c3045333c5ce62ed1426c61e28ce999f23cdfa 100644
--- a/ci-scripts/ran.py
+++ b/ci-scripts/ran.py
@@ -90,6 +90,7 @@ class RANManagement():
 		self.epcPcapFile = ''
 		self.htmlObj = None
 		self.epcObj = None
+		self.runtime_stats= ''
 
 
 
@@ -614,7 +615,7 @@ class RANManagement():
 			logging.debug('\u001B[1m Analyzing eNB replay logfile \u001B[0m')
 			logStatus = self.AnalyzeLogFile_eNB(extracted_log_file)
 			if self.htmlObj is not None:
-				self.htmlObj.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+				self.htmlObj.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
 			self.eNBLogFiles[int(self.eNB_instance)] = ''
 		else:
 			analyzeFile = False
@@ -643,10 +644,10 @@ class RANManagement():
 					return
 				else:
 					if self.htmlObj is not None:
-						self.htmlObj.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+						self.htmlObj.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
 			else:
 				if self.htmlObj is not None:
-					self.htmlObj.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+					self.htmlObj.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
 		self.eNBmbmsEnables[int(self.eNB_instance)] = False
 		self.eNBstatuses[int(self.eNB_instance)] = -1
 
@@ -712,16 +713,20 @@ class RANManagement():
 			if runTime != '':
 				result = re.search('Time executing user inst', str(line))
 				if result is not None:
-					userTime = 'to be decoded - 1'
+					fields=line.split(':')
+					userTime = 'userTime : ' + fields[1].replace('\n','')
 				result = re.search('Time executing system inst', str(line))
 				if result is not None:
-					systemTime = 'to be decoded - 2'
+					fields=line.split(':')
+					systemTime = 'systemTime : ' + fields[1].replace('\n','')
 				result = re.search('Max. Phy. memory usage:', str(line))
 				if result is not None:
-					maxPhyMemUsage = 'to be decoded - 3'
+					fields=line.split(':')
+					maxPhyMemUsage = 'maxPhyMemUsage : ' + fields[1].replace('\n','')
 				result = re.search('Number of context switch.*process origin', str(line))
 				if result is not None:
-					nbContextSwitches = 'to be decoded - 4'
+					fields=line.split(':')
+					nbContextSwitches = 'nbContextSwitches : ' + fields[1].replace('\n','')
 			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:
@@ -978,11 +983,12 @@ class RANManagement():
 			global_status = CONST.ENB_PROCESS_REALTIME_ISSUE
 		if self.htmlObj is not None:
 			self.htmlObj.htmleNBFailureMsg=htmleNBFailureMsg
-		# Runtime statistics
+		# Runtime statistics for console output and HTML
 		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)
+			logging.debug(userTime)
+			logging.debug(systemTime)
+			logging.debug(maxPhyMemUsage)
+			logging.debug(nbContextSwitches)
+			self.runtime_stats=runTime + '\n' + userTime + '\n' + systemTime + '\n' + maxPhyMemUsage + '\n' + nbContextSwitches
 		return global_status
diff --git a/ci-scripts/xml_files/fr1_toggle_cots_ue.xml b/ci-scripts/xml_files/fr1_toggle_cots_ue.xml
index b2267efc77dcc514bcf07eda0c2223be3ed5b46a..86c85f88b23288d13277fd4ef0b90e6cd5131135 100644
--- a/ci-scripts/xml_files/fr1_toggle_cots_ue.xml
+++ b/ci-scripts/xml_files/fr1_toggle_cots_ue.xml
@@ -32,7 +32,8 @@
 	<testCase id="010000">
 		<class>COTS_UE_Airplane</class>
 		<desc>Toggle COTS Airplane mode ON</desc>
-		<cots_ue_airplane_args>ON</cots_ue_airplane_args>
+		<cots_id>oppo</cots_id>
+		<cots_run_mode>ON</cots_run_mode>
 	</testCase>
 
 
diff --git a/doc/TESTBenches.md b/doc/TESTBenches.md
new file mode 100644
index 0000000000000000000000000000000000000000..14a70c321389b36e4fb3ea438e49e8d63d8899d3
--- /dev/null
+++ b/doc/TESTBenches.md
@@ -0,0 +1,34 @@
+
+## Table of Contents ##
+
+1.   [Legacy 1 Bench](#legacy-1-bench)
+2.   [Legacy 2 Bench](#legacy-2-bench)
+3.   [Next Bench for DEV](#next-bench-for-dev)
+4.   [Next Bench for CI](#next-bench-for-ci)
+5.   [Live Network Bench](#live-network-bench)
+6.   [Multi-RRU Bench](#multi-rru-bench)
+
+
+## Legacy 1 Bench
+
+![image info](./testbenches_doc_resources/legacy1.jpg)
+
+## Legacy 2 Bench
+
+![image info](./testbenches_doc_resources/legacy2.jpg)
+
+## Next Bench for DEV
+
+![image info](./testbenches_doc_resources/next_dev.jpg)
+
+## Next Bench for CI
+
+![image info](./testbenches_doc_resources/next_ci.jpg)
+
+## Live Network Bench
+
+![image info](./testbenches_doc_resources/live_network.jpg)
+
+## Multi-RRU Bench
+
+![image info](./testbenches_doc_resources/multi_rru.jpg)
diff --git a/doc/testbenches_doc_resources/legacy1.jpg b/doc/testbenches_doc_resources/legacy1.jpg
new file mode 100755
index 0000000000000000000000000000000000000000..f6cbb45c9a3664968ffd53bc6b0f92eb131f36c0
Binary files /dev/null and b/doc/testbenches_doc_resources/legacy1.jpg differ
diff --git a/doc/testbenches_doc_resources/legacy2.jpg b/doc/testbenches_doc_resources/legacy2.jpg
new file mode 100755
index 0000000000000000000000000000000000000000..538391172a518324ce20df994b65d45a4d2ba960
Binary files /dev/null and b/doc/testbenches_doc_resources/legacy2.jpg differ
diff --git a/doc/testbenches_doc_resources/live_network.jpg b/doc/testbenches_doc_resources/live_network.jpg
new file mode 100755
index 0000000000000000000000000000000000000000..786a5b5e3d48ad38534a72047cfd7e94087e9036
Binary files /dev/null and b/doc/testbenches_doc_resources/live_network.jpg differ
diff --git a/doc/testbenches_doc_resources/multi_rru.jpg b/doc/testbenches_doc_resources/multi_rru.jpg
new file mode 100755
index 0000000000000000000000000000000000000000..2c061221a2980ddb9072b24c3bef02b4e4a54011
Binary files /dev/null and b/doc/testbenches_doc_resources/multi_rru.jpg differ
diff --git a/doc/testbenches_doc_resources/next_ci.jpg b/doc/testbenches_doc_resources/next_ci.jpg
new file mode 100755
index 0000000000000000000000000000000000000000..4fd4c9a9861d8e058830970e650f4b14c8ac1d49
Binary files /dev/null and b/doc/testbenches_doc_resources/next_ci.jpg differ
diff --git a/doc/testbenches_doc_resources/next_dev.jpg b/doc/testbenches_doc_resources/next_dev.jpg
new file mode 100755
index 0000000000000000000000000000000000000000..ad9b37fdfa42edff980f42ce5d027e6aaa35b7c8
Binary files /dev/null and b/doc/testbenches_doc_resources/next_dev.jpg differ