1# Copyright 2022 - The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the 'License'); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an 'AS IS' BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15from acts.controllers.cellular_lib.BaseSimulation import BaseSimulation 16from acts.controllers.cellular_lib import BaseCellularDut 17 18 19class PresetSimulation(BaseSimulation): 20 """5G preset simulation. 21 22 The simulation will be configed by importing SCPI config file 23 instead of individually set params. 24 """ 25 26 # Keys to obtain settings from the test_config dictionary. 27 KEY_CELL_INFO = "cell_info" 28 KEY_SCPI_FILE_NAME = "scpi_file" 29 30 NETWORK_BIT_MASK = { 31 'nr_lte': '11000001000000000000' 32 } 33 ADB_CMD_LOCK_NETWORK = 'cmd phone set-allowed-network-types-for-users -s 0 {network_bit_mask}' 34 NR_LTE_BIT_MASK_KEY = 'nr_lte' 35 36 def __init__(self, 37 simulator, 38 log, 39 dut, 40 test_config, 41 calibration_table, 42 nr_mode=None): 43 """Initializes the simulator for 5G preset simulation. 44 45 Args: 46 simulator: a cellular simulator controller. 47 log: a logger handle. 48 dut: a device handler implementing BaseCellularDut. 49 test_config: test configuration obtained from the config file. 50 calibration_table: a dictionary containing path losses 51 for different bands. 52 """ 53 54 super().__init__(simulator, log, dut, test_config, calibration_table, 55 nr_mode) 56 # require param for idle test case 57 self.rrc_sc_timer = 0 58 59 # Set to KeySight APN 60 log.info('Configuring APN.') 61 self.dut.set_apn('Keysight', 'Keysight') 62 self.num_carriers = None 63 64 # Enable roaming on the phone 65 self.dut.toggle_data_roaming(True) 66 67 def setup_simulator(self): 68 """Do initial configuration in the simulator. """ 69 self.log.info('This simulation does not require initial setup.') 70 71 def configure(self, parameters): 72 """Configures simulation by importing scpi file. 73 74 A pre-made SCPI file include all the essential configuration 75 for the simulation is imported by send SCPI import command 76 to the callbox. 77 78 Args: 79 parameters: a configuration dictionary which includes scpi file path 80 if there is only one carrier, a list if there are multiple cells. 81 """ 82 scpi_file = parameters[0][self.KEY_SCPI_FILE_NAME] 83 cell_infos = parameters[0][self.KEY_CELL_INFO] 84 85 self.log.info('Configure test scenario with\n' + 86 f' SCPI config file: {scpi_file}\n' + 87 f' cell info: {cell_infos}') 88 89 self.simulator.import_configuration(scpi_file) 90 self.simulator.set_cell_info(cell_infos) 91 92 def start(self): 93 """Start simulation. 94 95 Waiting for the DUT to connect to the callbox. 96 97 Raise: 98 RuntimeError: simulation fail to start 99 due to unable to connect dut and cells. 100 """ 101 self.attach() 102 103 def attach(self): 104 """Attach UE to the callbox. 105 106 Toggle airplane mode on-off and wait for a specified timeout, 107 repeat until the UE connect to the callbox. 108 109 Raise: 110 RuntimeError: attaching fail 111 due to unable to connect dut and cells. 112 """ 113 try: 114 self.simulator.wait_until_attached(self.dut, self.attach_timeout, 115 self.attach_retries) 116 except Exception as exc: 117 raise RuntimeError('Could not attach to base station.') from exc 118 119 def calibrated_downlink_rx_power(self, bts_config, rsrp): 120 """Convert RSRP to total signal power from the basestation. 121 122 Args: 123 bts_config: the current configuration at the base station 124 rsrp: desired rsrp, contained in a key value pair 125 """ 126 raise NotImplementedError( 127 'This simulation mode does not support this configuration option') 128 129 def downlink_calibration(self, rat=None, power_units_conversion_func=None): 130 """Computes downlink path loss and returns the calibration value. 131 132 See base class implementation for details. 133 134 Args: 135 rat: ignored, replaced by 'lteRsrp'. 136 power_units_conversion_func: ignored, replaced by 137 self.rsrp_to_signal_power. 138 139 Returns: 140 Downlink calibration value and measured DL power. Note that the 141 phone only reports RSRP of the primary chain 142 """ 143 raise NotImplementedError( 144 'This simulation mode does not support this configuration option') 145 146 def rsrp_to_signal_power(self, rsrp, bts_config): 147 """Converts rsrp to total band signal power 148 149 RSRP is measured per subcarrier, so total band power needs to be 150 multiplied by the number of subcarriers being used. 151 152 Args: 153 rsrp: desired rsrp in dBm. 154 bts_config: a base station configuration object. 155 156 Returns: 157 Total band signal power in dBm 158 """ 159 raise NotImplementedError( 160 'This simulation mode does not support this configuration option') 161 162 def maximum_downlink_throughput(self): 163 """Calculates maximum achievable downlink throughput in. 164 165 The calculation is based on the current simulation state 166 Returns: 167 Maximum throughput in mbps. 168 """ 169 raise NotImplementedError( 170 'This simulation mode does not support this configuration option') 171 172 def bts_maximum_downlink_throughtput(self, bts_config): 173 """Calculates maximum achievable downlink throughput for a single 174 175 base station from its configuration object. 176 177 Args: 178 bts_config: a base station configuration object. 179 180 Returns: 181 Maximum throughput in mbps. 182 """ 183 raise NotImplementedError( 184 'This simulation mode does not support this configuration option') 185 186 def maximum_uplink_throughput(self): 187 """Calculates maximum achievable uplink throughput. 188 189 Returns: 190 Maximum throughput in mbps. 191 """ 192 raise NotImplementedError( 193 'This simulation mode does not support this configuration option') 194 195 def bts_maximum_uplink_throughtput(self, bts_config): 196 """Calculates maximum achievable uplink throughput 197 198 The calculation is for selected basestation 199 from its configuration object. 200 Args: 201 bts_config: an LTE base station configuration object. 202 203 Returns: 204 Maximum throughput in mbps. 205 206 """ 207 raise NotImplementedError( 208 'This simulation mode does not support this configuration option') 209 210 def calibrate(self, band): 211 """Calculates UL and DL path loss if it wasn't done before 212 213 Before running the base class implementation, configure the base station 214 to only use one downlink antenna with maximum bandwidth. 215 216 Args: 217 band: the band that is currently being calibrated. 218 """ 219 raise NotImplementedError( 220 'This simulation mode does not support this configuration option') 221 222 def start_traffic_for_calibration(self): 223 """If MAC padding is enabled, there is no need to start IP traffic. """ 224 raise NotImplementedError( 225 'This simulation mode does not support this configuration option') 226 227 def stop_traffic_for_calibration(self): 228 """If MAC padding is enabled, IP traffic wasn't started. """ 229 raise NotImplementedError( 230 'This simulation mode does not support this configuration option') 231 232 def get_measured_ul_power(self, samples=5, wait_after_sample=3): 233 """Calculates UL power. 234 235 The calculation is based on measurements from the callbox 236 and the calibration data. 237 Args: 238 samples: the numble of samples to average 239 wait_after_sample: time in seconds to wait in between samples 240 241 Returns: 242 the ul power at the UE antenna ports in dBs 243 """ 244 raise NotImplementedError( 245 'This simulation mode does not support this configuration option') 246