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. 16import time 17 18from acts.controllers.rohdeschwarz_lib import cmw500 19from acts.controllers import cellular_simulator as cc 20from acts.controllers.rohdeschwarz_lib import cmw500_scenario_generator as cg 21from acts.controllers.cellular_lib import LteSimulation 22 23CMW_TM_MAPPING = { 24 LteSimulation.TransmissionMode.TM1: cmw500.TransmissionModes.TM1, 25 LteSimulation.TransmissionMode.TM2: cmw500.TransmissionModes.TM2, 26 LteSimulation.TransmissionMode.TM3: cmw500.TransmissionModes.TM3, 27 LteSimulation.TransmissionMode.TM4: cmw500.TransmissionModes.TM4, 28 LteSimulation.TransmissionMode.TM7: cmw500.TransmissionModes.TM7, 29 LteSimulation.TransmissionMode.TM8: cmw500.TransmissionModes.TM8, 30 LteSimulation.TransmissionMode.TM9: cmw500.TransmissionModes.TM9 31} 32 33CMW_SCH_MAPPING = { 34 LteSimulation.SchedulingMode.STATIC: cmw500.SchedulingMode.USERDEFINEDCH 35} 36 37CMW_MIMO_MAPPING = { 38 LteSimulation.MimoMode.MIMO_1x1: cmw500.MimoModes.MIMO1x1, 39 LteSimulation.MimoMode.MIMO_2x2: cmw500.MimoModes.MIMO2x2, 40 LteSimulation.MimoMode.MIMO_4x4: cmw500.MimoModes.MIMO4x4 41} 42 43MIMO_ANTENNA_COUNT = { 44 LteSimulation.MimoMode.MIMO_1x1: 1, 45 LteSimulation.MimoMode.MIMO_2x2: 2, 46 LteSimulation.MimoMode.MIMO_4x4: 4, 47} 48 49IP_ADDRESS_TYPE_MAPPING = { 50 LteSimulation.IPAddressType.IPV4: cmw500.IPAddressType.IPV4, 51 LteSimulation.IPAddressType.IPV6: cmw500.IPAddressType.IPV6, 52 LteSimulation.IPAddressType.IPV4V6: cmw500.IPAddressType.IPV4V6, 53} 54 55# get mcs vs tbsi map with 256-qam disabled(downlink) 56get_mcs_tbsi_map_dl = { 57 cmw500.ModulationType.QPSK: { 58 0: 0, 59 1: 1, 60 2: 2, 61 3: 3, 62 4: 4, 63 5: 5, 64 6: 6, 65 7: 7, 66 8: 8, 67 9: 9 68 }, 69 cmw500.ModulationType.Q16: { 70 10: 9, 71 11: 10, 72 12: 11, 73 13: 12, 74 14: 13, 75 15: 14, 76 16: 15 77 }, 78 cmw500.ModulationType.Q64: { 79 17: 15, 80 18: 16, 81 19: 17, 82 20: 18, 83 21: 19, 84 22: 20, 85 23: 21, 86 24: 22, 87 25: 23, 88 26: 24, 89 27: 25, 90 28: 26 91 } 92} 93 94# get mcs vs tbsi map with 256-qam enabled(downlink) 95get_mcs_tbsi_map_for_256qam_dl = { 96 cmw500.ModulationType.QPSK: { 97 0: 0, 98 1: 2, 99 2: 4, 100 3: 6, 101 4: 8, 102 }, 103 cmw500.ModulationType.Q16: { 104 5: 10, 105 6: 11, 106 7: 12, 107 8: 13, 108 9: 14, 109 10: 15 110 }, 111 cmw500.ModulationType.Q64: { 112 11: 16, 113 12: 17, 114 13: 18, 115 14: 19, 116 15: 20, 117 16: 21, 118 17: 22, 119 18: 23, 120 19: 24 121 }, 122 cmw500.ModulationType.Q256: { 123 20: 25, 124 21: 27, 125 22: 28, 126 23: 29, 127 24: 30, 128 25: 31, 129 26: 32, 130 27: 33 131 } 132} 133 134# get mcs vs tbsi map (uplink) 135get_mcs_tbsi_map_ul = { 136 cmw500.ModulationType.QPSK: { 137 0: 0, 138 1: 1, 139 2: 2, 140 3: 3, 141 4: 4, 142 5: 5, 143 6: 6, 144 7: 7, 145 8: 8, 146 9: 9 147 }, 148 cmw500.ModulationType.Q16: { 149 10: 10, 150 11: 10, 151 12: 11, 152 13: 12, 153 14: 13, 154 15: 14, 155 16: 15, 156 17: 16, 157 18: 17, 158 19: 18, 159 20: 19, 160 21: 19, 161 22: 20, 162 23: 21, 163 24: 22, 164 25: 23, 165 26: 24, 166 27: 25, 167 28: 26 168 } 169} 170 171 172class CMW500CellularSimulator(cc.AbstractCellularSimulator): 173 """ A cellular simulator for telephony simulations based on the CMW 500 174 controller. """ 175 176 # The maximum number of carriers that this simulator can support for LTE 177 LTE_MAX_CARRIERS = 1 178 179 def __init__(self, ip_address, port): 180 """ Initializes the cellular simulator. 181 182 Args: 183 ip_address: the ip address of the CMW500 184 port: the port number for the CMW500 controller 185 """ 186 super().__init__() 187 188 try: 189 self.cmw = cmw500.Cmw500(ip_address, port) 190 except cmw500.CmwError: 191 raise cc.CellularSimulatorError('Could not connect to CMW500.') 192 193 self.bts = None 194 self.dl_modulation = None 195 self.ul_modulation = None 196 197 def destroy(self): 198 """ Sends finalization commands to the cellular equipment and closes 199 the connection. """ 200 self.cmw.disconnect() 201 202 def setup_lte_scenario(self): 203 """ Configures the equipment for an LTE simulation. """ 204 self.cmw.connection_type = cmw500.ConnectionType.DAU 205 # if bts has not yet been initialized 206 if not self.bts: 207 self.bts = [self.cmw.get_base_station()] 208 self.cmw.switch_lte_signalling(cmw500.LteState.LTE_ON) 209 210 def set_band_combination(self, bands, mimo_modes): 211 """ Prepares the test equipment for the indicated band/mimo combination. 212 213 Args: 214 bands: a list of bands represented as ints or strings 215 mimo_modes: a list of LteSimulation.MimoMode to use for each carrier 216 """ 217 self.num_carriers = len(bands) 218 self.bts = [self.cmw.get_base_station(cmw500.BtsNumber.BTS1)] 219 for i in range(1, len(bands)): 220 self.bts.append( 221 self.cmw.get_base_station(cmw500.BtsNumber('SCC{}'.format(i)))) 222 223 antennas = [MIMO_ANTENNA_COUNT[m] for m in mimo_modes] 224 self.set_scenario(bands, antennas) 225 226 def get_band_combination(self): 227 return [int(bts.band.strip('OB')) for bts in self.bts] 228 229 def set_lte_rrc_state_change_timer(self, enabled, time=10): 230 """ Configures the LTE RRC state change timer. 231 232 Args: 233 enabled: a boolean indicating if the timer should be on or off. 234 time: time in seconds for the timer to expire 235 """ 236 if enabled: 237 self.cmw.rrc_connection = cmw500.RrcState.RRC_OFF 238 self.cmw.rrc_connection_timer = time 239 else: 240 self.cmw.rrc_connection = cmw500.RrcState.RRC_ON 241 242 def set_band(self, bts_index, band): 243 """ Sets the band for the indicated base station. 244 245 Args: 246 bts_index: the base station number 247 band: the new band 248 """ 249 bts = self.bts[bts_index] 250 bts.duplex_mode = self.get_duplex_mode(band) 251 band = 'OB' + band 252 bts.band = band 253 self.log.debug('Band set to {}'.format(band)) 254 255 def get_duplex_mode(self, band): 256 """ Determines if the band uses FDD or TDD duplex mode 257 258 Args: 259 band: a band number 260 261 Returns: 262 an variable of class DuplexMode indicating if band is FDD or TDD 263 """ 264 if 33 <= int(band) <= 46: 265 return cmw500.DuplexMode.TDD 266 else: 267 return cmw500.DuplexMode.FDD 268 269 def set_input_power(self, bts_index, input_power): 270 """ Sets the input power for the indicated base station. 271 272 Args: 273 bts_index: the base station number 274 input_power: the new input power 275 """ 276 bts = self.bts[bts_index] 277 if input_power > 23: 278 self.log.warning('Open loop supports-50dBm to 23 dBm. ' 279 'Setting it to max power 23 dBm') 280 input_power = 23 281 bts.tpc_closed_loop_target_power = input_power 282 bts.uplink_power_control = input_power 283 bts.tpc_power_control = cmw500.TpcPowerControl.CLOSED_LOOP 284 285 def set_output_power(self, bts_index, output_power): 286 """ Sets the output power for the indicated base station. 287 288 Args: 289 bts_index: the base station number 290 output_power: the new output power 291 """ 292 bts = self.bts[bts_index] 293 bts.downlink_power_level = output_power 294 295 def set_tdd_config(self, bts_index, tdd_config): 296 """ Sets the tdd configuration number for the indicated base station. 297 298 Args: 299 bts_index: the base station number 300 tdd_config: the new tdd configuration number 301 """ 302 self.bts[bts_index].uldl_configuration = tdd_config 303 304 def set_ssf_config(self, bts_index, ssf_config): 305 """ Sets the Special Sub-Frame config number for the indicated 306 base station. 307 308 Args: 309 bts_index: the base station number 310 ssf_config: the new ssf config number 311 """ 312 if not 0 <= ssf_config <= 9: 313 raise ValueError('The Special Sub-Frame configuration has to be a ' 314 'number between 0 and 9.') 315 316 self.bts[bts_index].tdd_special_subframe = ssf_config 317 318 def set_bandwidth(self, bts_index, bandwidth): 319 """ Sets the bandwidth for the indicated base station. 320 321 Args: 322 bts_index: the base station number 323 bandwidth: the new bandwidth 324 """ 325 bts = self.bts[bts_index] 326 327 if bandwidth == 20: 328 bts.bandwidth = cmw500.LteBandwidth.BANDWIDTH_20MHz 329 elif bandwidth == 15: 330 bts.bandwidth = cmw500.LteBandwidth.BANDWIDTH_15MHz 331 elif bandwidth == 10: 332 bts.bandwidth = cmw500.LteBandwidth.BANDWIDTH_10MHz 333 elif bandwidth == 5: 334 bts.bandwidth = cmw500.LteBandwidth.BANDWIDTH_5MHz 335 elif bandwidth == 3: 336 bts.bandwidth = cmw500.LteBandwidth.BANDWIDTH_3MHz 337 elif bandwidth == 1.4: 338 bts.bandwidth = cmw500.LteBandwidth.BANDWIDTH_1MHz 339 else: 340 msg = 'Bandwidth {} MHz is not valid for LTE'.format(bandwidth) 341 raise ValueError(msg) 342 343 def set_downlink_channel_number(self, bts_index, channel_number): 344 """ Sets the downlink channel number for the indicated base station. 345 346 Args: 347 bts_index: the base station number 348 channel_number: the new channel number 349 """ 350 bts = self.bts[bts_index] 351 bts.dl_channel = channel_number 352 self.log.debug('Downlink Channel set to {}'.format(bts.dl_channel)) 353 354 def set_mimo_mode(self, bts_index, mimo_mode): 355 """ Sets the mimo mode for the indicated base station. 356 357 Args: 358 bts_index: the base station number 359 mimo_mode: the new mimo mode 360 """ 361 bts = self.bts[bts_index] 362 mimo_mode = CMW_MIMO_MAPPING[mimo_mode] 363 if mimo_mode == cmw500.MimoModes.MIMO1x1: 364 self.set_bts_antenna(bts_index, 1) 365 bts.dl_antenna = cmw500.MimoModes.MIMO1x1 366 367 elif mimo_mode == cmw500.MimoModes.MIMO2x2: 368 self.set_bts_antenna(bts_index, 2) 369 bts.dl_antenna = cmw500.MimoModes.MIMO2x2 370 # set default transmission mode and DCI for this scenario 371 bts.transmode = cmw500.TransmissionModes.TM3 372 bts.dci_format = cmw500.DciFormat.D2A 373 374 elif mimo_mode == cmw500.MimoModes.MIMO4x4: 375 self.set_bts_antenna(bts_index, 4) 376 bts.dl_antenna = cmw500.MimoModes.MIMO4x4 377 else: 378 raise RuntimeError('The requested MIMO mode is not supported.') 379 380 def set_bts_antenna(self, bts_index, antenna_count): 381 """ Sets the mimo mode for a particular component carrier. 382 383 Args: 384 bts_index: index of the base station to configure. 385 antenna_count: number of antennas to use for the component carrier 386 either (1, 2, 4) 387 """ 388 antennas = self.get_antenna_combination() 389 antennas[bts_index] = antenna_count 390 bands = self.get_band_combination() 391 self.set_scenario(bands, antennas) 392 393 def get_antenna_combination(self): 394 """ Gets the current antenna configuration. 395 396 Returns: 397 antenna_count: a list containing the number of antennas to use for 398 each bts/CC. 399 """ 400 cmd = 'ROUTe:LTE:SIGN:SCENario?' 401 scenario_name = self.cmw.send_and_recv(cmd) 402 return cg.get_antennas(scenario_name) 403 404 def set_scenario(self, bands, antennas): 405 """ Sets the MIMO scenario on the CMW. 406 407 Args: 408 bands: a list defining the bands to use for each CC. 409 antennas: a list of integers defining the number of antennas to use 410 for each bts/CC. 411 """ 412 self.log.debug('Setting scenario: bands: {}, antennas: {}'.format( 413 bands, antennas)) 414 scenario = cg.get_scenario(bands, antennas) 415 cmd = 'ROUTe:LTE:SIGN:SCENario:{}:FLEXible {}'.format( 416 scenario.name, scenario.routing) 417 self.cmw.send_and_recv(cmd) 418 self.cmw.scc_activation_mode = cmw500.SccActivationMode.AUTO 419 420 # apply requested bands now 421 for i, band in enumerate(bands): 422 self.set_band(i, str(band)) 423 424 def set_transmission_mode(self, bts_index, tmode): 425 """ Sets the transmission mode for the indicated base station. 426 427 Args: 428 bts_index: the base station number 429 tmode: the new transmission mode 430 """ 431 bts = self.bts[bts_index] 432 433 tmode = CMW_TM_MAPPING[tmode] 434 435 if (tmode in [ 436 cmw500.TransmissionModes.TM1, cmw500.TransmissionModes.TM7 437 ] and bts.dl_antenna == cmw500.MimoModes.MIMO1x1.value): 438 bts.transmode = tmode 439 elif (tmode.value in cmw500.TransmissionModes.__members__ 440 and bts.dl_antenna == cmw500.MimoModes.MIMO2x2.value): 441 bts.transmode = tmode 442 elif (tmode in [ 443 cmw500.TransmissionModes.TM2, cmw500.TransmissionModes.TM3, 444 cmw500.TransmissionModes.TM4, cmw500.TransmissionModes.TM9 445 ] and bts.dl_antenna == cmw500.MimoModes.MIMO4x4.value): 446 bts.transmode = tmode 447 448 else: 449 raise ValueError('Transmission modes should support the current ' 450 'mimo mode') 451 452 def set_scheduling_mode(self, 453 bts_index, 454 scheduling, 455 mcs_dl=None, 456 mcs_ul=None, 457 nrb_dl=None, 458 nrb_ul=None): 459 """ Sets the scheduling mode for the indicated base station. 460 461 Args: 462 bts_index: the base station number. 463 scheduling: the new scheduling mode. 464 mcs_dl: Downlink MCS. 465 mcs_ul: Uplink MCS. 466 nrb_dl: Number of RBs for downlink. 467 nrb_ul: Number of RBs for uplink. 468 """ 469 bts = self.bts[bts_index] 470 bts.reduced_pdcch = cmw500.ReducedPdcch.ON 471 472 scheduling = CMW_SCH_MAPPING[scheduling] 473 bts.scheduling_mode = scheduling 474 475 if not (self.ul_modulation and self.dl_modulation): 476 raise ValueError('Modulation should be set prior to scheduling ' 477 'call') 478 479 if scheduling == cmw500.SchedulingMode.RMC: 480 481 if not nrb_ul and nrb_dl: 482 raise ValueError('nrb_ul and nrb dl should not be none') 483 484 bts.rb_configuration_ul = (nrb_ul, self.ul_modulation, 'KEEP') 485 self.log.info('ul rb configurations set to {}'.format( 486 bts.rb_configuration_ul)) 487 488 time.sleep(1) 489 490 self.log.debug('Setting rb configurations for down link') 491 bts.rb_configuration_dl = (nrb_dl, self.dl_modulation, 'KEEP') 492 self.log.info('dl rb configurations set to {}'.format( 493 bts.rb_configuration_ul)) 494 495 elif scheduling == cmw500.SchedulingMode.USERDEFINEDCH: 496 497 if not all([nrb_ul, nrb_dl, mcs_dl, mcs_ul]): 498 raise ValueError('All parameters are mandatory.') 499 500 tbs = get_mcs_tbsi_map_ul[self.ul_modulation][mcs_ul] 501 502 bts.rb_configuration_ul = (nrb_ul, 0, self.ul_modulation, tbs) 503 self.log.info('ul rb configurations set to {}'.format( 504 bts.rb_configuration_ul)) 505 506 time.sleep(1) 507 508 if self.dl_256_qam_enabled: 509 tbs = get_mcs_tbsi_map_for_256qam_dl[ 510 self.dl_modulation][mcs_dl] 511 else: 512 tbs = get_mcs_tbsi_map_dl[self.dl_modulation][mcs_dl] 513 514 bts.rb_configuration_dl = (nrb_dl, 0, self.dl_modulation, tbs) 515 self.log.info('dl rb configurations set to {}'.format( 516 bts.rb_configuration_dl)) 517 518 def set_dl_256_qam_enabled(self, bts_index, enabled): 519 """ Determines what MCS table should be used for the downlink. 520 This only saves the setting that will be used when configuring MCS. 521 522 Args: 523 bts_index: the base station number 524 enabled: whether 256 QAM should be used 525 """ 526 self.log.info('Set 256 QAM DL MCS enabled: ' + str(enabled)) 527 self.dl_modulation = cmw500.ModulationType.Q256 if enabled \ 528 else cmw500.ModulationType.Q64 529 self.dl_256_qam_enabled = enabled 530 531 def set_ul_64_qam_enabled(self, bts_index, enabled): 532 """ Determines what MCS table should be used for the uplink. 533 This only saves the setting that will be used when configuring MCS. 534 535 Args: 536 bts_index: the base station number 537 enabled: whether 64 QAM should be used 538 """ 539 self.log.info('Set 64 QAM UL MCS enabled: ' + str(enabled)) 540 self.ul_modulation = cmw500.ModulationType.Q64 if enabled \ 541 else cmw500.ModulationType.Q16 542 self.ul_64_qam_enabled = enabled 543 544 def set_mac_padding(self, bts_index, mac_padding): 545 """ Enables or disables MAC padding in the indicated base station. 546 547 Args: 548 bts_index: the base station number 549 mac_padding: the new MAC padding setting 550 """ 551 # TODO (b/143918664): CMW500 doesn't have an equivalent setting. 552 553 def set_cfi(self, bts_index, cfi): 554 """ Sets the Channel Format Indicator for the indicated base station. 555 556 Args: 557 bts_index: the base station number 558 cfi: the new CFI setting 559 """ 560 # TODO (b/143497738): implement. 561 self.log.error('Setting CFI is not yet implemented in the CMW500 ' 562 'controller.') 563 564 def set_paging_cycle(self, bts_index, cycle_duration): 565 """ Sets the paging cycle duration for the indicated base station. 566 567 Args: 568 bts_index: the base station number 569 cycle_duration: the new paging cycle duration in milliseconds 570 """ 571 # TODO (b/146068532): implement. 572 self.log.error('Setting the paging cycle duration is not yet ' 573 'implemented in the CMW500 controller.') 574 575 def set_phich_resource(self, bts_index, phich): 576 """ Sets the PHICH Resource setting for the indicated base station. 577 578 Args: 579 bts_index: the base station number 580 phich: the new PHICH resource setting 581 """ 582 self.log.error('Configuring the PHICH resource setting is not yet ' 583 'implemented in the CMW500 controller.') 584 585 def set_drx_connected_mode(self, bts_index, active): 586 """ Sets the time interval to wait before entering DRX mode 587 588 Args: 589 bts_index: the base station number 590 active: Boolean indicating whether cDRX mode 591 is active 592 """ 593 self.cmw.drx_connected_mode = (cmw500.DrxMode.USER_DEFINED 594 if active else cmw500.DrxMode.OFF) 595 596 def set_drx_on_duration_timer(self, bts_index, timer): 597 """ Sets the amount of PDCCH subframes to wait for data after 598 waking up from a DRX cycle 599 600 Args: 601 bts_index: the base station number 602 timer: Number of PDCCH subframes to wait and check for user data 603 after waking from the DRX cycle 604 """ 605 timer = 'PSF{}'.format(timer) 606 self.cmw.drx_on_duration_timer = timer 607 608 def set_drx_inactivity_timer(self, bts_index, timer): 609 """ Sets the number of PDCCH subframes to wait before entering DRX mode 610 611 Args: 612 bts_index: the base station number 613 timer: The amount of time to wait before entering DRX mode 614 """ 615 timer = 'PSF{}'.format(timer) 616 self.cmw.drx_inactivity_timer = timer 617 618 def set_drx_retransmission_timer(self, bts_index, timer): 619 """ Sets the number of consecutive PDCCH subframes to wait 620 for retransmission 621 622 Args: 623 bts_index: the base station number 624 timer: Number of PDCCH subframes to remain active 625 """ 626 timer = 'PSF{}'.format(timer) 627 self.cmw.drx_retransmission_timer = timer 628 629 def set_drx_long_cycle(self, bts_index, cycle): 630 """ Sets the amount of subframes representing a DRX long cycle. 631 632 Args: 633 bts_index: the base station number 634 cycle: The amount of subframes representing one long DRX cycle. 635 One cycle consists of DRX sleep + DRX on duration 636 """ 637 cycle = 'SF{}'.format(cycle) 638 self.cmw.drx_long_cycle = cycle 639 640 def set_drx_long_cycle_offset(self, bts_index, offset): 641 """ Sets the offset used to determine the subframe number 642 to begin the long drx cycle 643 644 Args: 645 bts_index: the base station number 646 offset: Number in range 0 to (long cycle - 1) 647 """ 648 self.cmw.drx_long_cycle_offset = offset 649 650 def set_apn(self, apn): 651 """ Configures the callbox network Access Point Name. 652 653 Args: 654 apn: the APN name 655 """ 656 self.cmw.apn = apn 657 658 def set_ip_type(self, ip_type): 659 """ Configures the callbox network IP type. 660 661 Args: 662 ip_type: the network type to use. 663 """ 664 self.cmw.ip_type = IP_ADDRESS_TYPE_MAPPING[ip_type] 665 666 def set_mtu(self, mtu): 667 """ Configures the callbox network Maximum Transmission Unit. 668 669 Args: 670 mtu: the MTU size. 671 """ 672 self.cmw.mtu = mtu 673 674 def lte_attach_secondary_carriers(self, ue_capability_enquiry): 675 """ Activates the secondary carriers for CA. Requires the DUT to be 676 attached to the primary carrier first. 677 678 Args: 679 ue_capability_enquiry: UE capability enquiry message to be sent to 680 the UE before starting carrier aggregation. 681 """ 682 for i in range(1, len(self.bts)): 683 bts = self.bts[i] 684 if bts.scc_state == cmw500.SccState.OFF.value: 685 if (self.cmw.scc_activation_mode == 686 cmw500.SccActivationMode.MANUAL.value): 687 self.cmw.switch_scc_state(i, cmw500.SccState.ON) 688 # SEMI_AUTO -> directly to MAC activation 689 if (self.cmw.scc_activation_mode == 690 cmw500.SccActivationMode.SEMI_AUTO.value): 691 self.cmw.switch_scc_state(i, cmw500.SccState.MAC) 692 693 # no need to do anything for auto 694 if self.cmw.scc_activation_mode != cmw500.SccActivationMode.AUTO.value: 695 if bts.scc_state == cmw500.SccState.ON.value: 696 self.cmw.switch_scc_state(i, cmw500.SccState.RRC) 697 698 if bts.scc_state == cmw500.SccState.RRC.value: 699 self.cmw.switch_scc_state(i, cmw500.SccState.MAC) 700 701 self.cmw.wait_for_scc_state(i, [cmw500.SccState.MAC]) 702 703 def wait_until_attached(self, timeout=120): 704 """ Waits until the DUT is attached to the primary carrier. 705 706 Args: 707 timeout: after this amount of time the method will raise a 708 CellularSimulatorError exception. Default is 120 seconds. 709 """ 710 try: 711 self.cmw.wait_for_attached_state(timeout=timeout) 712 except cmw500.CmwError: 713 raise cc.CellularSimulatorError('The phone was not in ' 714 'attached state before ' 715 'the timeout period ended.') 716 717 def wait_until_communication_state(self, timeout=120): 718 """ Waits until the DUT is in Communication state. 719 720 Args: 721 timeout: after this amount of time the method will raise a 722 CellularSimulatorError exception. Default is 120 seconds. 723 """ 724 try: 725 self.cmw.wait_for_rrc_state(cmw500.LTE_CONN_RESP, timeout=timeout) 726 except cmw500.CmwError: 727 raise cc.CellularSimulatorError('The phone was not in ' 728 'Communication state before ' 729 'the timeout period ended.') 730 731 def wait_until_idle_state(self, timeout=120): 732 """ Waits until the DUT is in Idle state. 733 734 Args: 735 timeout: after this amount of time the method will raise a 736 CellularSimulatorError exception. Default is 120 seconds. 737 """ 738 try: 739 self.cmw.wait_for_rrc_state(cmw500.LTE_IDLE_RESP, timeout=timeout) 740 except cmw500.CmwError: 741 raise cc.CellularSimulatorError('The phone was not in ' 742 'Idle state before ' 743 'the timeout period ended.') 744 745 def wait_until_quiet(self, timeout=120): 746 """Waits for all pending operations to finish on the simulator. 747 748 Args: 749 timeout: after this amount of time the method will raise a 750 CellularSimulatorError exception. Default is 120 seconds. 751 """ 752 self.cmw.send_and_recv('*OPC?') 753 754 def detach(self): 755 """ Turns off all the base stations so the DUT loose connection.""" 756 self.cmw.detach() 757 758 def stop(self): 759 """ Stops current simulation. After calling this method, the simulator 760 will need to be set up again. """ 761 self.detach() 762 self.cmw.switch_lte_signalling(cmw500.LteState.LTE_OFF) 763 764 def start_data_traffic(self): 765 """ Starts transmitting data from the instrument to the DUT. """ 766 raise NotImplementedError() 767 768 def stop_data_traffic(self): 769 """ Stops transmitting data from the instrument to the DUT. """ 770 raise NotImplementedError() 771 772 def send_sms(self, message): 773 """ Sends an SMS message to the DUT. 774 775 Args: 776 message: the SMS message to send. 777 """ 778 self.cmw.set_sms(message) 779 self.cmw.send_sms() 780