1#!/usr/bin/env python3 2# 3# Copyright 2019 - The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the 'License'); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an 'AS IS' BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16from acts import logger 17from acts.test_utils.power import tel_simulations as sims 18 19 20class AbstractCellularSimulator: 21 """ A generic cellular simulator controller class that can be derived to 22 implement equipment specific classes and allows the tests to be implemented 23 without depending on a singular instrument model. 24 25 This class defines the interface that every cellular simulator controller 26 needs to implement and shouldn't be instantiated by itself. """ 27 28 # Indicates if it is able to use 256 QAM as the downlink modulation for LTE 29 LTE_SUPPORTS_DL_256QAM = None 30 31 # Indicates if it is able to use 64 QAM as the uplink modulation for LTE 32 LTE_SUPPORTS_UL_64QAM = None 33 34 # Indicates if 4x4 MIMO is supported for LTE 35 LTE_SUPPORTS_4X4_MIMO = None 36 37 # The maximum number of carriers that this simulator can support for LTE 38 LTE_MAX_CARRIERS = None 39 40 # The maximum power that the equipment is able to transmit 41 MAX_DL_POWER = None 42 43 def __init__(self): 44 """ Initializes the cellular simulator. """ 45 self.log = logger.create_tagged_trace_logger('CellularSimulator') 46 47 def destroy(self): 48 """ Sends finalization commands to the cellular equipment and closes 49 the connection. """ 50 raise NotImplementedError() 51 52 def setup_lte_scenario(self): 53 """ Configures the equipment for an LTE simulation. """ 54 raise NotImplementedError() 55 56 def setup_lte_ca_scenario(self): 57 """ Configures the equipment for an LTE with CA simulation. """ 58 raise NotImplementedError() 59 60 def set_ca_combination(self, combination): 61 """ Prepares the test equipment for the indicated CA combination. 62 63 The reason why this is implemented in a separate method and not calling 64 LteSimulation.BtsConfig for each separate band is that configuring each 65 ssc cannot be done separately, as it is necessary to know which 66 carriers are on the same band in order to decide which RF outputs can 67 be shared in the test equipment. 68 69 Args: 70 combination: carrier aggregation configurations are indicated 71 with a list of strings consisting of the band number followed 72 by the CA class. For example, for 5 CA using 3C 7C and 28A 73 the parameter value should be [3c, 7c, 28a]. 74 """ 75 raise NotImplementedError() 76 77 def configure_bts(self, config, bts_index=0): 78 """ Commands the equipment to setup a base station with the required 79 configuration. This method applies configurations that are common to all 80 RATs. 81 82 Args: 83 config: a BaseSimulation.BtsConfig object. 84 bts_index: the base station number. 85 """ 86 87 if config.output_power: 88 self.set_output_power(bts_index, config.output_power) 89 90 if config.input_power: 91 self.set_input_power(bts_index, config.input_power) 92 93 if isinstance(config, sims.LteSimulation.LteSimulation.BtsConfig): 94 self.configure_lte_bts(config, bts_index) 95 96 def configure_lte_bts(self, config, bts_index=0): 97 """ Commands the equipment to setup an LTE base station with the 98 required configuration. 99 100 Args: 101 config: an LteSimulation.BtsConfig object. 102 bts_index: the base station number. 103 """ 104 if config.band: 105 self.set_band(bts_index, config.band) 106 107 if config.dlul_config: 108 self.set_tdd_config(bts_index, config.dlul_config) 109 110 if config.ssf_config: 111 self.set_ssf_config(bts_index, config.ssf_config) 112 113 if config.bandwidth: 114 self.set_bandwidth(bts_index, config.bandwidth) 115 116 if config.dl_channel: 117 self.set_downlink_channel_number(bts_index, config.dl_channel) 118 119 if config.mimo_mode: 120 self.set_mimo_mode(bts_index, config.mimo_mode) 121 122 if config.transmission_mode: 123 self.set_transmission_mode(bts_index, config.transmission_mode) 124 125 # Modulation order should be set before set_scheduling_mode being 126 # called. 127 if config.dl_modulation_order: 128 self.set_dl_modulation(bts_index, config.dl_modulation_order) 129 130 if config.ul_modulation_order: 131 self.set_ul_modulation(bts_index, config.ul_modulation_order) 132 133 if config.scheduling_mode: 134 135 if (config.scheduling_mode == 136 sims.LteSimulation.SchedulingMode.STATIC 137 and not (config.dl_rbs and config.ul_rbs and config.dl_mcs 138 and config.ul_mcs)): 139 raise ValueError('When the scheduling mode is set to manual, ' 140 'the RB and MCS parameters are required.') 141 142 # If scheduling mode is set to Dynamic, the RB and MCS parameters 143 # will be ignored by set_scheduling_mode. 144 self.set_scheduling_mode(bts_index, config.scheduling_mode, 145 config.dl_mcs, config.ul_mcs, 146 config.dl_rbs, config.ul_rbs) 147 148 # This variable stores a boolean value so the following is needed to 149 # differentiate False from None 150 if config.tbs_pattern_on is not None: 151 self.set_tbs_pattern_on(bts_index, config.tbs_pattern_on) 152 153 if config.cfi: 154 self.set_cfi(bts_index, config.cfi) 155 156 if config.paging_cycle: 157 self.set_paging_cycle(bts_index, config.paging_cycle) 158 159 if config.phich: 160 self.set_phich_resource(bts_index, config.phich) 161 162 if config.drx_connected_mode: 163 self.set_drx_connected_mode(bts_index, config.drx_connected_mode) 164 165 if config.drx_on_duration_timer: 166 self.set_drx_on_duration_timer(bts_index, 167 config.drx_on_duration_timer) 168 169 if config.drx_inactivity_timer: 170 self.set_drx_inactivity_timer(bts_index, 171 config.drx_inactivity_timer) 172 173 if config.drx_retransmission_timer: 174 self.set_drx_retransmission_timer( 175 bts_index, config.drx_retransmission_timer) 176 177 if config.drx_long_cycle: 178 self.set_drx_long_cycle(bts_index, config.drx_long_cycle) 179 180 if config.drx_long_cycle_offset is not None: 181 self.set_drx_long_cycle_offset(bts_index, 182 config.drx_long_cycle_offset) 183 184 def set_lte_rrc_state_change_timer(self, enabled, time=10): 185 """ Configures the LTE RRC state change timer. 186 187 Args: 188 enabled: a boolean indicating if the timer should be on or off. 189 time: time in seconds for the timer to expire 190 """ 191 raise NotImplementedError() 192 193 def set_band(self, bts_index, band): 194 """ Sets the band for the indicated base station. 195 196 Args: 197 bts_index: the base station number 198 band: the new band 199 """ 200 raise NotImplementedError() 201 202 def set_input_power(self, bts_index, input_power): 203 """ Sets the input power for the indicated base station. 204 205 Args: 206 bts_index: the base station number 207 input_power: the new input power 208 """ 209 raise NotImplementedError() 210 211 def set_output_power(self, bts_index, output_power): 212 """ Sets the output power for the indicated base station. 213 214 Args: 215 bts_index: the base station number 216 output_power: the new output power 217 """ 218 raise NotImplementedError() 219 220 def set_tdd_config(self, bts_index, tdd_config): 221 """ Sets the tdd configuration number for the indicated base station. 222 223 Args: 224 bts_index: the base station number 225 tdd_config: the new tdd configuration number 226 """ 227 raise NotImplementedError() 228 229 def set_ssf_config(self, bts_index, ssf_config): 230 """ Sets the Special Sub-Frame config number for the indicated 231 base station. 232 233 Args: 234 bts_index: the base station number 235 ssf_config: the new ssf config number 236 """ 237 raise NotImplementedError() 238 239 def set_bandwidth(self, bts_index, bandwidth): 240 """ Sets the bandwidth for the indicated base station. 241 242 Args: 243 bts_index: the base station number 244 bandwidth: the new bandwidth 245 """ 246 raise NotImplementedError() 247 248 def set_downlink_channel_number(self, bts_index, channel_number): 249 """ Sets the downlink channel number for the indicated base station. 250 251 Args: 252 bts_index: the base station number 253 channel_number: the new channel number 254 """ 255 raise NotImplementedError() 256 257 def set_mimo_mode(self, bts_index, mimo_mode): 258 """ Sets the mimo mode for the indicated base station. 259 260 Args: 261 bts_index: the base station number 262 mimo_mode: the new mimo mode 263 """ 264 raise NotImplementedError() 265 266 def set_transmission_mode(self, bts_index, transmission_mode): 267 """ Sets the transmission mode for the indicated base station. 268 269 Args: 270 bts_index: the base station number 271 transmission_mode: the new transmission mode 272 """ 273 raise NotImplementedError() 274 275 def set_scheduling_mode(self, bts_index, scheduling_mode, mcs_dl, mcs_ul, 276 nrb_dl, nrb_ul): 277 """ Sets the scheduling mode for the indicated base station. 278 279 Args: 280 bts_index: the base station number 281 scheduling_mode: the new scheduling mode 282 mcs_dl: Downlink MCS (only for STATIC scheduling) 283 mcs_ul: Uplink MCS (only for STATIC scheduling) 284 nrb_dl: Number of RBs for downlink (only for STATIC scheduling) 285 nrb_ul: Number of RBs for uplink (only for STATIC scheduling) 286 """ 287 raise NotImplementedError() 288 289 def set_dl_modulation(self, bts_index, modulation): 290 """ Sets the DL modulation for the indicated base station. 291 292 Args: 293 bts_index: the base station number 294 modulation: the new DL modulation 295 """ 296 raise NotImplementedError() 297 298 def set_ul_modulation(self, bts_index, modulation): 299 """ Sets the UL modulation for the indicated base station. 300 301 Args: 302 bts_index: the base station number 303 modulation: the new UL modulation 304 """ 305 raise NotImplementedError() 306 307 def set_tbs_pattern_on(self, bts_index, tbs_pattern_on): 308 """ Enables or disables TBS pattern in the indicated base station. 309 310 Args: 311 bts_index: the base station number 312 tbs_pattern_on: the new TBS pattern setting 313 """ 314 raise NotImplementedError() 315 316 def set_cfi(self, bts_index, cfi): 317 """ Sets the Channel Format Indicator for the indicated base station. 318 319 Args: 320 bts_index: the base station number 321 cfi: the new CFI setting 322 """ 323 raise NotImplementedError() 324 325 def set_paging_cycle(self, bts_index, cycle_duration): 326 """ Sets the paging cycle duration for the indicated base station. 327 328 Args: 329 bts_index: the base station number 330 cycle_duration: the new paging cycle duration in milliseconds 331 """ 332 raise NotImplementedError() 333 334 def set_phich_resource(self, bts_index, phich): 335 """ Sets the PHICH Resource setting for the indicated base station. 336 337 Args: 338 bts_index: the base station number 339 phich: the new PHICH resource setting 340 """ 341 raise NotImplementedError() 342 343 def set_drx_connected_mode(self, bts_index, active): 344 """ Sets the time interval to wait before entering DRX mode 345 346 Args: 347 bts_index: the base station number 348 active: Boolean indicating whether cDRX mode 349 is active 350 """ 351 raise NotImplementedError() 352 353 def set_drx_on_duration_timer(self, bts_index, timer): 354 """ Sets the amount of PDCCH subframes to wait for data after 355 waking up from a DRX cycle 356 357 Args: 358 bts_index: the base station number 359 timer: Number of PDCCH subframes to wait and check for user data 360 after waking from the DRX cycle 361 """ 362 raise NotImplementedError() 363 364 def set_drx_inactivity_timer(self, bts_index, timer): 365 """ Sets the number of PDCCH subframes to wait before entering DRX mode 366 367 Args: 368 bts_index: the base station number 369 timer: The amount of time to wait before entering DRX mode 370 """ 371 raise NotImplementedError() 372 373 def set_drx_retransmission_timer(self, bts_index, timer): 374 """ Sets the number of consecutive PDCCH subframes to wait 375 for retransmission 376 377 Args: 378 bts_index: the base station number 379 timer: Number of PDCCH subframes to remain active 380 381 """ 382 raise NotImplementedError() 383 384 def set_drx_long_cycle(self, bts_index, cycle): 385 """ Sets the amount of subframes representing a DRX long cycle. 386 387 Args: 388 bts_index: the base station number 389 cycle: The amount of subframes representing one long DRX cycle. 390 One cycle consists of DRX sleep + DRX on duration 391 """ 392 raise NotImplementedError() 393 394 def set_drx_long_cycle_offset(self, bts_index, offset): 395 """ Sets the offset used to determine the subframe number 396 to begin the long drx cycle 397 398 Args: 399 bts_index: the base station number 400 offset: Number in range 0 to (long cycle - 1) 401 """ 402 raise NotImplementedError() 403 404 def lte_attach_secondary_carriers(self, ue_capability_enquiry): 405 """ Activates the secondary carriers for CA. Requires the DUT to be 406 attached to the primary carrier first. 407 408 Args: 409 ue_capability_enquiry: UE capability enquiry message to be sent to 410 the UE before starting carrier aggregation. 411 """ 412 raise NotImplementedError() 413 414 def wait_until_attached(self, timeout=120): 415 """ Waits until the DUT is attached to the primary carrier. 416 417 Args: 418 timeout: after this amount of time the method will raise a 419 CellularSimulatorError exception. Default is 120 seconds. 420 """ 421 raise NotImplementedError() 422 423 def wait_until_communication_state(self, timeout=120): 424 """ Waits until the DUT is in Communication state. 425 426 Args: 427 timeout: after this amount of time the method will raise a 428 CellularSimulatorError exception. Default is 120 seconds. 429 """ 430 raise NotImplementedError() 431 432 def wait_until_idle_state(self, timeout=120): 433 """ Waits until the DUT is in Idle state. 434 435 Args: 436 timeout: after this amount of time the method will raise a 437 CellularSimulatorError exception. Default is 120 seconds. 438 """ 439 raise NotImplementedError() 440 441 def detach(self): 442 """ Turns off all the base stations so the DUT loose connection.""" 443 raise NotImplementedError() 444 445 def stop(self): 446 """ Stops current simulation. After calling this method, the simulator 447 will need to be set up again. """ 448 raise NotImplementedError() 449 450 def start_data_traffic(self): 451 """ Starts transmitting data from the instrument to the DUT. """ 452 raise NotImplementedError() 453 454 def stop_data_traffic(self): 455 """ Stops transmitting data from the instrument to the DUT. """ 456 raise NotImplementedError() 457 458 def get_measured_pusch_power(self): 459 """ Queries PUSCH power measured at the callbox. 460 461 Returns: 462 The PUSCH power in the primary input port. 463 """ 464 raise NotImplementedError() 465 466 467class CellularSimulatorError(Exception): 468 """ Exceptions thrown when the cellular equipment is unreachable or it 469 returns an error after receiving a command. """ 470 pass 471