blob: 79b35a673d3b24a6c71ed69e70b6abded6ff8419 [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright 2019 - The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
#
# 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.
import math
import ntpath
import time
import acts.controllers.cellular_simulator as cc
from acts.controllers.cellular_lib import LteSimulation
from acts.controllers.anritsu_lib import md8475a
from acts.controllers.anritsu_lib import _anritsu_utils as anritsu
class MD8475CellularSimulator(cc.AbstractCellularSimulator):
MD8475_VERSION = 'A'
# Indicates if it is able to use 256 QAM as the downlink modulation for LTE
LTE_SUPPORTS_DL_256QAM = False
# Indicates if it is able to use 64 QAM as the uplink modulation for LTE
LTE_SUPPORTS_UL_64QAM = False
# Indicates if 4x4 MIMO is supported for LTE
LTE_SUPPORTS_4X4_MIMO = False
# The maximum number of carriers that this simulator can support for LTE
LTE_MAX_CARRIERS = 2
# The maximum power that the equipment is able to transmit
MAX_DL_POWER = -10
# Simulation config files in the callbox computer.
# These should be replaced in the future by setting up
# the same configuration manually.
LTE_BASIC_SIM_FILE = 'SIM_default_LTE.wnssp'
LTE_BASIC_CELL_FILE = 'CELL_LTE_config.wnscp'
LTE_CA_BASIC_SIM_FILE = 'SIM_LTE_CA.wnssp'
LTE_CA_BASIC_CELL_FILE = 'CELL_LTE_CA_config.wnscp'
# Filepath to the config files stored in the Anritsu callbox. Needs to be
# formatted to replace {} with either A or B depending on the model.
CALLBOX_CONFIG_PATH = 'C:\\Users\\MD8475A\\Documents\\DAN_configs\\'
def __init__(self, ip_address):
""" Initializes the cellular simulator.
Args:
ip_address: the ip address of the MD8475 instrument
"""
super().__init__()
try:
self.anritsu = md8475a.MD8475A(ip_address,
md8475_version=self.MD8475_VERSION)
except anritsu.AnritsuError:
raise cc.CellularSimulatorError('Could not connect to MD8475.')
self.bts = None
def destroy(self):
""" Sends finalization commands to the cellular equipment and closes
the connection. """
self.anritsu.stop_simulation()
self.anritsu.disconnect()
def setup_lte_scenario(self):
""" Configures the equipment for an LTE simulation. """
cell_file_name = self.LTE_BASIC_CELL_FILE
sim_file_name = self.LTE_BASIC_SIM_FILE
cell_file_path = ntpath.join(self.CALLBOX_CONFIG_PATH, cell_file_name)
sim_file_path = ntpath.join(self.CALLBOX_CONFIG_PATH, sim_file_name)
self.anritsu.load_simulation_paramfile(sim_file_path)
self.anritsu.load_cell_paramfile(cell_file_path)
# MD4875A supports only 2 carriers. The MD4875B class adds other cells.
self.bts = [
self.anritsu.get_BTS(md8475a.BtsNumber.BTS1),
self.anritsu.get_BTS(md8475a.BtsNumber.BTS2)
]
def set_band_combination(self, bands, mimo_modes):
""" Prepares the test equipment for the indicated band combination.
The reason why this is implemented in a separate method and not calling
LteSimulation.BtsConfig for each separate band is that configuring each
ssc cannot be done separately, as it is necessary to know which
carriers are on the same band in order to decide which RF outputs can
be shared in the test equipment.
Args:
bands: a list of bands represented as ints or strings
mimo_modes: a list of LteSimulation.MimoMode to use for each carrier
"""
self.num_carriers = len(bands)
# Validate the number of carriers.
if self.num_carriers > self.LTE_MAX_CARRIERS:
raise cc.CellularSimulatorError('The test equipment supports up '
'to {} carriers.'.format(
self.LTE_MAX_CARRIERS))
# Initialize the base stations in the test equipment
self.anritsu.set_simulation_model(
*[md8475a.BtsTechnology.LTE for _ in range(self.num_carriers)],
reset=False)
# If base stations use different bands, make sure that the RF cards are
# not being shared by setting the right maximum MIMO modes
if self.num_carriers == 2:
# RF cards are never shared when doing 2CA so 4X4 can be done in
# both base stations.
self.bts[0].mimo_support = md8475a.LteMimoMode.MIMO_4X4
self.bts[1].mimo_support = md8475a.LteMimoMode.MIMO_4X4
elif self.num_carriers == 3:
# 4X4 can only be done in the second base station if it is shared
# with the primary. If the RF cards cannot be shared, then at most
# 2X2 can be done.
self.bts[0].mimo_support = md8475a.LteMimoMode.MIMO_4X4
if bands[0] == bands[1]:
self.bts[1].mimo_support = md8475a.LteMimoMode.MIMO_4X4
else:
self.bts[1].mimo_support = md8475a.LteMimoMode.MIMO_2X2
self.bts[2].mimo_support = md8475a.LteMimoMode.MIMO_2X2
elif self.num_carriers > 3:
raise NotImplementedError('The controller doesn\'t implement more '
'than 3 carriers for MD8475B yet.')
# Enable carrier aggregation if there is more than one carrier
if self.num_carriers > 1:
self.anritsu.set_carrier_aggregation_enabled()
# Restart the simulation as changing the simulation model will stop it.
self.anritsu.start_simulation()
def set_input_power(self, bts_index, input_power):
""" Sets the input power for the indicated base station.
Args:
bts_index: the base station number
input_power: the new input power
"""
nrb_ul = int(self.bts[bts_index].nrb_ul)
max_nrb_ul = self.bts[bts_index].max_nrb_ul
input_level = str(
round(input_power - 10 * math.log10(nrb_ul / max_nrb_ul), 1))
if nrb_ul < max_nrb_ul:
self.log.info('Number of UL RBs ({}) is less than the maximum RB '
'allocation ({}). Increasing UL reference power to '
'{} dbm to compensate'.format(
nrb_ul, max_nrb_ul, input_level))
self.bts[bts_index].input_level = input_level
def set_output_power(self, bts_index, output_power):
""" Sets the output power for the indicated base station.
Args:
bts_index: the base station number
output_power: the new output power
"""
self.bts[bts_index].output_level = output_power
def set_downlink_channel_number(self, bts_index, channel_number):
""" Sets the downlink channel number for the indicated base station.
Args:
bts_index: the base station number
channel_number: the new channel number
"""
# Temporarily adding this line to workaround a bug in the
# Anritsu callbox in which the channel number needs to be set
# to a different value before setting it to the final one.
self.bts[bts_index].dl_channel = str(int(channel_number + 1))
time.sleep(8)
self.bts[bts_index].dl_channel = str(int(channel_number))
def set_dl_256_qam_enabled(self, bts_index, enabled):
""" Determines what MCS table should be used for the downlink.
Args:
bts_index: the base station number
enabled: whether 256 QAM should be used
"""
if enabled and not self.LTE_SUPPORTS_DL_256QAM:
raise RuntimeError('256 QAM is not supported')
self.bts[bts_index].lte_dl_modulation_order = \
md8475a.ModulationType.Q256 if enabled else md8475a.ModulationType.Q64
def set_ul_64_qam_enabled(self, bts_index, enabled):
""" Determines what MCS table should be used for the uplink.
Args:
bts_index: the base station number
enabled: whether 64 QAM should be used
"""
self.bts[bts_index].lte_ul_modulation_order = \
md8475a.ModulationType.Q64 if enabled else md8475a.ModulationType.Q16
def set_mac_padding(self, bts_index, mac_padding):
""" Enables or disables MAC padding in the indicated base station.
Args:
bts_index: the base station number
mac_padding: the new MAC padding setting
"""
if mac_padding:
self.bts[bts_index].tbs_pattern = 'FULLALLOCATION'
else:
self.bts[bts_index].tbs_pattern = 'OFF'
def set_lte_rrc_state_change_timer(self, enabled, time=10):
""" Configures the LTE RRC state change timer.
Args:
enabled: a boolean indicating if the timer should be on or off.
time: time in seconds for the timer to expire
"""
self.anritsu.set_lte_rrc_status_change(enabled)
if enabled:
self.anritsu.set_lte_rrc_status_change_timer(time)
def set_cfi(self, bts_index, cfi):
""" Sets the Channel Format Indicator for the indicated base station.
Args:
bts_index: the base station number
cfi: the new CFI setting
"""
self.bts[bts_index].cfi = cfi
def set_paging_cycle(self, bts_index, cycle_duration):
""" Sets the paging cycle duration for the indicated base station.
Args:
bts_index: the base station number
cycle_duration: the new paging cycle duration in milliseconds
"""
# TODO (b/146068532): implement.
self.bts[bts_index].paging_duration = cycle_duration
def set_phich_resource(self, bts_index, phich):
""" Sets the PHICH Resource setting for the indicated base station.
Args:
bts_index: the base station number
phich: the new PHICH resource setting
"""
self.bts[bts_index].phich_resource = phich
def set_drx_connected_mode(self, bts_index, active):
""" Sets the DRX connected mode
Args:
bts_index: the base station number
active: Boolean indicating whether cDRX mode
is active
"""
mode = 'MANUAL' if active else 'OFF'
self.bts[bts_index].drx_connected_mode = mode
def set_drx_on_duration_timer(self, bts_index, timer):
""" Sets the amount of PDCCH subframes to wait for data after
waking up from a DRX cycle
Args:
bts_index: the base station number
timer: Number of PDCCH subframes to wait and check for user data
after waking from the DRX cycle
"""
self.bts[bts_index].drx_on_duration_timer = timer
def set_drx_inactivity_timer(self, bts_index, timer):
""" Sets the number of PDCCH subframes to wait before entering DRX mode
Args:
bts_index: the base station number
timer: The time interval to wait before entering DRX mode
"""
self.bts[bts_index].drx_inactivity_timer = timer
def set_drx_retransmission_timer(self, bts_index, timer):
""" Sets the number of consecutive PDCCH subframes to wait
for retransmission
Args:
bts_index: the base station number
timer: Number of PDCCH subframes to remain active
"""
self.bts[bts_index].drx_retransmission_timer = timer
def set_drx_long_cycle(self, bts_index, cycle):
""" Sets the amount of subframes representing a DRX long cycle.
Args:
bts_index: the base station number
cycle: The amount of subframes representing one long DRX cycle.
One cycle consists of DRX sleep + DRX on duration
"""
self.bts[bts_index].drx_long_cycle = cycle
def set_drx_long_cycle_offset(self, bts_index, offset):
""" Sets the offset used to determine the subframe number
to begin the long drx cycle
Args:
bts_index: the base station number
offset: Number in range 0 to (long cycle - 1)
"""
self.bts[bts_index].drx_long_cycle_offset = offset
def set_band(self, bts_index, band):
""" Sets the right duplex mode before switching to a new band.
Args:
bts_index: the base station number
band: desired band
"""
bts = self.bts[bts_index]
# The callbox won't restore the band-dependent default values if the
# request is to switch to the same band as the one the base station is
# currently using. To ensure that default values are restored, go to a
# different band before switching.
if int(bts.band) == band:
# Using bands 1 and 2 but it could be any others
bts.band = '1' if band != 1 else '2'
# Switching to config.band will be handled by the parent class
# implementation of this method.
bts.duplex_mode = self.get_duplex_mode(band).value
bts.band = band
time.sleep(5) # It takes some time to propagate the new band
def get_duplex_mode(self, band):
""" Determines if the band uses FDD or TDD duplex mode
Args:
band: a band number
Returns:
an variable of class DuplexMode indicating if band is FDD or TDD
"""
if 33 <= int(band) <= 46:
return LteSimulation.DuplexMode.TDD
else:
return LteSimulation.DuplexMode.FDD
def set_tdd_config(self, bts_index, config):
""" Sets the frame structure for TDD bands.
Args:
bts_index: the base station number
config: the desired frame structure. An int between 0 and 6.
"""
if not 0 <= config <= 6:
raise ValueError("The frame structure configuration has to be a "
"number between 0 and 6")
self.bts[bts_index].uldl_configuration = config
# Wait for the setting to propagate
time.sleep(5)
def set_ssf_config(self, bts_index, ssf_config):
""" Sets the Special Sub-Frame config number for the indicated
base station.
Args:
bts_index: the base station number
ssf_config: the new ssf config number
"""
# Cast to int in case it was passed as a string
ssf_config = int(ssf_config)
if not 0 <= ssf_config <= 9:
raise ValueError('The Special Sub-Frame configuration has to be a '
'number between 0 and 9.')
self.bts[bts_index].tdd_special_subframe = ssf_config
def set_bandwidth(self, bts_index, bandwidth):
""" Sets the LTE channel bandwidth (MHz)
Args:
bts_index: the base station number
bandwidth: desired bandwidth (MHz)
"""
bts = self.bts[bts_index]
if bandwidth == 20:
bts.bandwidth = md8475a.BtsBandwidth.LTE_BANDWIDTH_20MHz
elif bandwidth == 15:
bts.bandwidth = md8475a.BtsBandwidth.LTE_BANDWIDTH_15MHz
elif bandwidth == 10:
bts.bandwidth = md8475a.BtsBandwidth.LTE_BANDWIDTH_10MHz
elif bandwidth == 5:
bts.bandwidth = md8475a.BtsBandwidth.LTE_BANDWIDTH_5MHz
elif bandwidth == 3:
bts.bandwidth = md8475a.BtsBandwidth.LTE_BANDWIDTH_3MHz
elif bandwidth == 1.4:
bts.bandwidth = md8475a.BtsBandwidth.LTE_BANDWIDTH_1dot4MHz
else:
msg = "Bandwidth = {} MHz is not valid for LTE".format(bandwidth)
self.log.error(msg)
raise ValueError(msg)
time.sleep(5) # It takes some time to propagate the new settings
def set_mimo_mode(self, bts_index, mimo):
""" Sets the number of DL antennas for the desired MIMO mode.
Args:
bts_index: the base station number
mimo: object of class MimoMode
"""
bts = self.bts[bts_index]
# If the requested mimo mode is not compatible with the current TM,
# warn the user before changing the value.
if mimo == LteSimulation.MimoMode.MIMO_1x1:
if bts.transmode not in [
LteSimulation.TransmissionMode.TM1,
LteSimulation.TransmissionMode.TM7
]:
self.log.warning(
"Using only 1 DL antennas is not allowed with "
"the current transmission mode. Changing the "
"number of DL antennas will override this "
"setting.")
bts.dl_antenna = 1
elif mimo == LteSimulation.MimoMode.MIMO_2x2:
if bts.transmode not in [
LteSimulation.TransmissionMode.TM2,
LteSimulation.TransmissionMode.TM3,
LteSimulation.TransmissionMode.TM4,
LteSimulation.TransmissionMode.TM8,
LteSimulation.TransmissionMode.TM9
]:
self.log.warning("Using two DL antennas is not allowed with "
"the current transmission mode. Changing the "
"number of DL antennas will override this "
"setting.")
bts.dl_antenna = 2
elif mimo == LteSimulation.MimoMode.MIMO_4x4 and \
self.LTE_SUPPORTS_4X4_MIMO:
if bts.transmode not in [
LteSimulation.TransmissionMode.TM2,
LteSimulation.TransmissionMode.TM3,
LteSimulation.TransmissionMode.TM4,
LteSimulation.TransmissionMode.TM9
]:
self.log.warning("Using four DL antennas is not allowed with "
"the current transmission mode. Changing the "
"number of DL antennas will override this "
"setting.")
bts.dl_antenna = 4
else:
RuntimeError("The requested MIMO mode is not supported.")
def set_scheduling_mode(self, bts_index, scheduling, mcs_dl, mcs_ul,
nrb_dl, nrb_ul):
""" Sets the scheduling mode for LTE
Args:
bts_index: the base station number
scheduling: DYNAMIC or STATIC scheduling (Enum list)
mcs_dl: Downlink MCS (only for STATIC scheduling)
mcs_ul: Uplink MCS (only for STATIC scheduling)
nrb_dl: Number of RBs for downlink (only for STATIC scheduling)
nrb_ul: Number of RBs for uplink (only for STATIC scheduling)
"""
bts = self.bts[bts_index]
bts.lte_scheduling_mode = scheduling.value
if scheduling == LteSimulation.SchedulingMode.STATIC:
if not all([nrb_dl, nrb_ul, mcs_dl, mcs_ul]):
raise ValueError('When the scheduling mode is set to manual, '
'the RB and MCS parameters are required.')
bts.packet_rate = md8475a.BtsPacketRate.LTE_MANUAL
bts.lte_mcs_dl = mcs_dl
bts.lte_mcs_ul = mcs_ul
bts.nrb_dl = nrb_dl
bts.nrb_ul = nrb_ul
time.sleep(5) # It takes some time to propagate the new settings
def lte_attach_secondary_carriers(self, ue_capability_enquiry):
""" Activates the secondary carriers for CA. Requires the DUT to be
attached to the primary carrier first.
Args:
ue_capability_enquiry: UE capability enquiry message to be sent to
the UE before starting carrier aggregation.
"""
# Trigger UE capability enquiry from network to get
# UE supported CA band combinations. Here freq_bands is a hex string.
self.anritsu.trigger_ue_capability_enquiry(ue_capability_enquiry)
testcase = self.anritsu.get_AnritsuTestCases()
# A bug in the instrument's software (b/139547391) requires the test
# procedure to be set to whatever was the previous configuration before
# setting it to MULTICELL.
testcase.procedure = md8475a.TestProcedure(testcase.procedure)
testcase.procedure = md8475a.TestProcedure.PROCEDURE_MULTICELL
testcase.power_control = md8475a.TestPowerControl.POWER_CONTROL_DISABLE
testcase.measurement_LTE = md8475a.TestMeasurement.MEASUREMENT_DISABLE
# Enable the secondary carrier base stations for CA
for bts_index in range(1, self.num_carriers):
self.bts[bts_index].dl_cc_enabled = True
self.anritsu.start_testcase()
retry_counter = 0
self.log.info("Waiting for the test case to start...")
time.sleep(5)
while self.anritsu.get_testcase_status() == "0":
retry_counter += 1
if retry_counter == 3:
raise RuntimeError(
"The test case failed to start after {} "
"retries. The connection between the phone "
"and the base station might be unstable.".format(
retry_counter))
time.sleep(10)
def set_transmission_mode(self, bts_index, tmode):
""" Sets the transmission mode for the LTE basetation
Args:
bts_index: the base station number
tmode: Enum list from class 'TransmissionModeLTE'
"""
bts = self.bts[bts_index]
# If the selected transmission mode does not support the number of DL
# antennas, throw an exception.
if (tmode in [
LteSimulation.TransmissionMode.TM1,
LteSimulation.TransmissionMode.TM7
] and bts.dl_antenna != '1'):
# TM1 and TM7 only support 1 DL antenna
raise ValueError("{} allows only one DL antenna. Change the "
"number of DL antennas before setting the "
"transmission mode.".format(tmode.value))
elif (tmode == LteSimulation.TransmissionMode.TM8
and bts.dl_antenna != '2'):
# TM8 requires 2 DL antennas
raise ValueError("TM2 requires two DL antennas. Change the "
"number of DL antennas before setting the "
"transmission mode.")
elif (tmode in [
LteSimulation.TransmissionMode.TM2,
LteSimulation.TransmissionMode.TM3,
LteSimulation.TransmissionMode.TM4,
LteSimulation.TransmissionMode.TM9
] and bts.dl_antenna == '1'):
# TM2, TM3, TM4 and TM9 require 2 or 4 DL antennas
raise ValueError("{} requires at least two DL atennas. Change the "
"number of DL antennas before setting the "
"transmission mode.".format(tmode.value))
# The TM mode is allowed for the current number of DL antennas, so it
# is safe to change this setting now
bts.transmode = tmode.value
time.sleep(5) # It takes some time to propagate the new settings
def wait_until_attached(self, timeout=120):
""" Waits until the DUT is attached to the primary carrier.
Args:
timeout: after this amount of time the method will raise a
CellularSimulatorError exception. Default is 120 seconds.
"""
try:
self.anritsu.wait_for_registration_state(time_to_wait=timeout)
except anritsu.AnritsuError:
raise cc.CellularSimulatorError('The phone did not attach before '
'the timeout period ended.')
def wait_until_communication_state(self, timeout=120):
""" Waits until the DUT is in Communication state.
Args:
timeout: after this amount of time the method will raise a
CellularSimulatorError exception. Default is 120 seconds.
"""
try:
self.anritsu.wait_for_communication_state(time_to_wait=timeout)
except anritsu.AnritsuError:
raise cc.CellularSimulatorError('The phone was not in '
'Communication state before '
'the timeout period ended.')
def wait_until_idle_state(self, timeout=120):
""" Waits until the DUT is in Idle state.
Args:
timeout: after this amount of time the method will raise a
CellularSimulatorError exception. Default is 120 seconds.
"""
try:
self.anritsu.wait_for_idle_state(time_to_wait=timeout)
except anritsu.AnritsuError:
raise cc.CellularSimulatorError('The phone was not in Idle state '
'before the time the timeout '
'period ended.')
def detach(self):
""" Turns off all the base stations so the DUT loose connection."""
if self.anritsu.get_smartstudio_status() == \
md8475a.ProcessingStatus.PROCESS_STATUS_NOTRUN.value:
self.log.info('Device cannot be detached because simulation is '
'not running.')
return
self.anritsu.set_simulation_state_to_poweroff()
def stop(self):
""" Stops current simulation. After calling this method, the simulator
will need to be set up again. """
self.anritsu.stop_simulation()
def start_data_traffic(self):
""" Starts transmitting data from the instrument to the DUT. """
try:
self.anritsu.start_ip_traffic()
except md8475a.AnritsuError as inst:
# This typically happens when traffic is already running.
# TODO (b/141962691): continue only if traffic is running
self.log.warning(str(inst))
time.sleep(4)
def stop_data_traffic(self):
""" Stops transmitting data from the instrument to the DUT. """
try:
self.anritsu.stop_ip_traffic()
except md8475a.AnritsuError as inst:
# This typically happens when traffic has already been stopped
# TODO (b/141962691): continue only if traffic is stopped
self.log.warning(str(inst))
time.sleep(2)
def get_measured_pusch_power(self):
""" Queries PUSCH power measured at the callbox.
Returns:
The PUSCH power in the primary input port.
"""
# Try three times before raising an exception. This is needed because
# the callbox sometimes reports an active chain as 'DEACTIVE'.
retries_left = 3
while retries_left > 0:
ul_pusch = self.anritsu.get_measured_pusch_power().split(',')[0]
if ul_pusch != 'DEACTIVE':
return float(ul_pusch)
time.sleep(3)
retries_left -= 1
self.log.info('Chain shows as inactive. %d retries left.' %
retries_left)
raise cc.CellularSimulatorError('Could not get measured PUSCH power.')
class MD8475BCellularSimulator(MD8475CellularSimulator):
MD8475_VERSION = 'B'
# Indicates if it is able to use 256 QAM as the downlink modulation for LTE
LTE_SUPPORTS_DL_256QAM = True
# Indicates if it is able to use 64 QAM as the uplink modulation for LTE
LTE_SUPPORTS_UL_64QAM = True
# Indicates if 4x4 MIMO is supported for LTE
LTE_SUPPORTS_4X4_MIMO = True
# The maximum number of carriers that this simulator can support for LTE
LTE_MAX_CARRIERS = 4
# The maximum power that the equipment is able to transmit
MAX_DL_POWER = -10
# Simulation config files in the callbox computer.
# These should be replaced in the future by setting up
# the same configuration manually.
LTE_BASIC_SIM_FILE = 'SIM_default_LTE.wnssp2'
LTE_BASIC_CELL_FILE = 'CELL_LTE_config.wnscp2'
LTE_CA_BASIC_SIM_FILE = 'SIM_LTE_CA.wnssp2'
LTE_CA_BASIC_CELL_FILE = 'CELL_LTE_CA_config.wnscp2'
# Filepath to the config files stored in the Anritsu callbox. Needs to be
# formatted to replace {} with either A or B depending on the model.
CALLBOX_CONFIG_PATH = 'C:\\Users\\MD8475B\\Documents\\DAN_configs\\'
def setup_lte_scenario(self):
""" The B model can support up to five carriers. """
super().setup_lte_scenario()
self.bts.extend([
self.anritsu.get_BTS(md8475a.BtsNumber.BTS3),
self.anritsu.get_BTS(md8475a.BtsNumber.BTS4),
self.anritsu.get_BTS(md8475a.BtsNumber.BTS5)
])