• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.controllers import cellular_lib
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    # The maximum number of carriers that this simulator can support for LTE
29    LTE_MAX_CARRIERS = None
30
31    # The maximum power that the equipment is able to transmit
32    MAX_DL_POWER = None
33
34    def __init__(self):
35        """ Initializes the cellular simulator. """
36        self.log = logger.create_tagged_trace_logger('CellularSimulator')
37        self.num_carriers = None
38
39    def destroy(self):
40        """ Sends finalization commands to the cellular equipment and closes
41        the connection. """
42        raise NotImplementedError()
43
44    def setup_lte_scenario(self):
45        """ Configures the equipment for an LTE simulation. """
46        raise NotImplementedError()
47
48    def set_band_combination(self, bands, mimo_modes):
49        """ Prepares the test equipment for the indicated band/mimo combination.
50
51        Args:
52            bands: a list of bands represented as ints or strings
53            mimo_modes: a list of LteSimulation.MimoMode to use for each antenna
54        """
55        raise NotImplementedError()
56
57    def configure_bts(self, config, bts_index=0):
58        """ Commands the equipment to setup a base station with the required
59        configuration. This method applies configurations that are common to all
60        RATs.
61
62        Args:
63            config: a BaseSimulation.BtsConfig object.
64            bts_index: the base station number.
65        """
66
67        config_vars = vars(config)
68        config_dict = {
69            key: config_vars[key]
70            for key in config_vars if config_vars[key]
71        }
72        self.log.info('The config for {} is {}'.format(bts_index, config_dict))
73
74        if config.output_power:
75            self.set_output_power(bts_index, config.output_power)
76
77        if config.input_power:
78            self.set_input_power(bts_index, config.input_power)
79
80        if isinstance(config, cellular_lib.LteCellConfig.LteCellConfig):
81            self.configure_lte_bts(config, bts_index)
82
83        if isinstance(config, cellular_lib.NrCellConfig.NrCellConfig):
84            self.configure_nr_bts(config, bts_index)
85
86    def configure_lte_bts(self, config, bts_index=0):
87        """ Commands the equipment to setup an LTE base station with the
88        required configuration.
89
90        Args:
91            config: an LteSimulation.BtsConfig object.
92            bts_index: the base station number.
93        """
94        if config.band:
95            self.set_band(bts_index, config.band)
96
97        if config.dlul_config:
98            self.set_tdd_config(bts_index, config.dlul_config)
99
100        if config.ssf_config:
101            self.set_ssf_config(bts_index, config.ssf_config)
102
103        if config.bandwidth:
104            self.set_bandwidth(bts_index, config.bandwidth)
105
106        if config.dl_channel:
107            self.set_downlink_channel_number(bts_index, config.dl_channel)
108
109        if config.mimo_mode:
110            self.set_mimo_mode(bts_index, config.mimo_mode)
111
112        if config.transmission_mode:
113            self.set_transmission_mode(bts_index, config.transmission_mode)
114
115        # Modulation order should be set before set_scheduling_mode being
116        # called.
117        if config.dl_256_qam_enabled is not None:
118            self.set_dl_256_qam_enabled(bts_index, config.dl_256_qam_enabled)
119
120        if config.ul_64_qam_enabled is not None:
121            self.set_ul_64_qam_enabled(bts_index, config.ul_64_qam_enabled)
122
123        if config.scheduling_mode:
124
125            if (config.scheduling_mode
126                    == cellular_lib.LteSimulation.SchedulingMode.STATIC
127                    and not (config.dl_rbs and config.ul_rbs and config.dl_mcs
128                             and config.ul_mcs)):
129                raise ValueError('When the scheduling mode is set to manual, '
130                                 'the RB and MCS parameters are required.')
131
132            # If scheduling mode is set to Dynamic, the RB and MCS parameters
133            # will be ignored by set_scheduling_mode.
134            self.set_scheduling_mode(bts_index, config.scheduling_mode,
135                                     config.dl_mcs, config.ul_mcs,
136                                     config.dl_rbs, config.ul_rbs)
137
138        # This variable stores a boolean value so the following is needed to
139        # differentiate False from None
140        if config.mac_padding is not None:
141            self.set_mac_padding(bts_index, config.mac_padding)
142
143        if config.cfi:
144            self.set_cfi(bts_index, config.cfi)
145
146        if config.paging_cycle:
147            self.set_paging_cycle(bts_index, config.paging_cycle)
148
149        if config.phich:
150            self.set_phich_resource(bts_index, config.phich)
151
152        if config.drx_connected_mode:
153            self.set_drx_connected_mode(bts_index, config.drx_connected_mode)
154
155            if config.drx_on_duration_timer:
156                self.set_drx_on_duration_timer(bts_index,
157                                               config.drx_on_duration_timer)
158
159            if config.drx_inactivity_timer:
160                self.set_drx_inactivity_timer(bts_index,
161                                              config.drx_inactivity_timer)
162
163            if config.drx_retransmission_timer:
164                self.set_drx_retransmission_timer(
165                    bts_index, config.drx_retransmission_timer)
166
167            if config.drx_long_cycle:
168                self.set_drx_long_cycle(bts_index, config.drx_long_cycle)
169
170            if config.drx_long_cycle_offset is not None:
171                self.set_drx_long_cycle_offset(bts_index,
172                                               config.drx_long_cycle_offset)
173
174    def configure_nr_bts(self, config, bts_index=1):
175        """ Commands the equipment to setup an LTE base station with the
176        required configuration.
177
178        Args:
179            config: an LteSimulation.BtsConfig object.
180            bts_index: the base station number.
181        """
182        if config.band:
183            self.set_band(bts_index, config.band)
184
185        if config.nr_arfcn:
186            self.set_downlink_channel_number(bts_index, config.nr_arfcn)
187
188        if config.bandwidth:
189            self.set_bandwidth(bts_index, config.bandwidth)
190
191        if config.mimo_mode:
192            self.set_mimo_mode(bts_index, config.mimo_mode)
193
194        if config.scheduling_mode:
195
196            if (config.scheduling_mode
197                    == cellular_lib.LteSimulation.SchedulingMode.STATIC
198                    and not (config.dl_rbs and config.ul_rbs and config.dl_mcs
199                             and config.ul_mcs)):
200                raise ValueError('When the scheduling mode is set to manual, '
201                                 'the RB and MCS parameters are required.')
202
203            # If scheduling mode is set to Dynamic, the RB and MCS parameters
204            # will be ignored by set_scheduling_mode.
205            self.set_scheduling_mode(bts_index, config.scheduling_mode,
206                                     config.dl_mcs, config.ul_mcs,
207                                     config.dl_rbs, config.ul_rbs)
208        if config.mac_padding is not None:
209            self.set_mac_padding(bts_index, config.mac_padding)
210
211    def set_lte_rrc_state_change_timer(self, enabled, time=10):
212        """ Configures the LTE RRC state change timer.
213
214        Args:
215            enabled: a boolean indicating if the timer should be on or off.
216            time: time in seconds for the timer to expire
217        """
218        raise NotImplementedError()
219
220    def set_band(self, bts_index, band):
221        """ Sets the band for the indicated base station.
222
223        Args:
224            bts_index: the base station number
225            band: the new band
226        """
227        raise NotImplementedError()
228
229    def set_input_power(self, bts_index, input_power):
230        """ Sets the input power for the indicated base station.
231
232        Args:
233            bts_index: the base station number
234            input_power: the new input power
235        """
236        raise NotImplementedError()
237
238    def set_output_power(self, bts_index, output_power):
239        """ Sets the output power for the indicated base station.
240
241        Args:
242            bts_index: the base station number
243            output_power: the new output power
244        """
245        raise NotImplementedError()
246
247    def set_tdd_config(self, bts_index, tdd_config):
248        """ Sets the tdd configuration number for the indicated base station.
249
250        Args:
251            bts_index: the base station number
252            tdd_config: the new tdd configuration number
253        """
254        raise NotImplementedError()
255
256    def set_ssf_config(self, bts_index, ssf_config):
257        """ Sets the Special Sub-Frame config number for the indicated
258        base station.
259
260        Args:
261            bts_index: the base station number
262            ssf_config: the new ssf config number
263        """
264        raise NotImplementedError()
265
266    def set_bandwidth(self, bts_index, bandwidth):
267        """ Sets the bandwidth for the indicated base station.
268
269        Args:
270            bts_index: the base station number
271            bandwidth: the new bandwidth
272        """
273        raise NotImplementedError()
274
275    def set_downlink_channel_number(self, bts_index, channel_number):
276        """ Sets the downlink channel number for the indicated base station.
277
278        Args:
279            bts_index: the base station number
280            channel_number: the new channel number
281        """
282        raise NotImplementedError()
283
284    def set_mimo_mode(self, bts_index, mimo_mode):
285        """ Sets the mimo mode for the indicated base station.
286
287        Args:
288            bts_index: the base station number
289            mimo_mode: the new mimo mode
290        """
291        raise NotImplementedError()
292
293    def set_transmission_mode(self, bts_index, transmission_mode):
294        """ Sets the transmission mode for the indicated base station.
295
296        Args:
297            bts_index: the base station number
298            transmission_mode: the new transmission mode
299        """
300        raise NotImplementedError()
301
302    def set_scheduling_mode(self, bts_index, scheduling_mode, mcs_dl, mcs_ul,
303                            nrb_dl, nrb_ul):
304        """ Sets the scheduling mode for the indicated base station.
305
306        Args:
307            bts_index: the base station number
308            scheduling_mode: the new scheduling mode
309            mcs_dl: Downlink MCS (only for STATIC scheduling)
310            mcs_ul: Uplink MCS (only for STATIC scheduling)
311            nrb_dl: Number of RBs for downlink (only for STATIC scheduling)
312            nrb_ul: Number of RBs for uplink (only for STATIC scheduling)
313        """
314        raise NotImplementedError()
315
316    def set_dl_256_qam_enabled(self, bts_index, enabled):
317        """ Determines what MCS table should be used for the downlink.
318
319        Args:
320            bts_index: the base station number
321            enabled: whether 256 QAM should be used
322        """
323        raise NotImplementedError()
324
325    def set_ul_64_qam_enabled(self, bts_index, enabled):
326        """ Determines what MCS table should be used for the uplink.
327
328        Args:
329            bts_index: the base station number
330            enabled: whether 64 QAM should be used
331        """
332        raise NotImplementedError()
333
334    def set_mac_padding(self, bts_index, mac_padding):
335        """ Enables or disables MAC padding in the indicated base station.
336
337        Args:
338            bts_index: the base station number
339            mac_padding: the new MAC padding setting
340        """
341        raise NotImplementedError()
342
343    def set_cfi(self, bts_index, cfi):
344        """ Sets the Channel Format Indicator for the indicated base station.
345
346        Args:
347            bts_index: the base station number
348            cfi: the new CFI setting
349        """
350        raise NotImplementedError()
351
352    def set_paging_cycle(self, bts_index, cycle_duration):
353        """ Sets the paging cycle duration for the indicated base station.
354
355        Args:
356            bts_index: the base station number
357            cycle_duration: the new paging cycle duration in milliseconds
358        """
359        raise NotImplementedError()
360
361    def set_phich_resource(self, bts_index, phich):
362        """ Sets the PHICH Resource setting for the indicated base station.
363
364        Args:
365            bts_index: the base station number
366            phich: the new PHICH resource setting
367        """
368        raise NotImplementedError()
369
370    def set_drx_connected_mode(self, bts_index, active):
371        """ Sets the time interval to wait before entering DRX mode
372
373        Args:
374            bts_index: the base station number
375            active: Boolean indicating whether cDRX mode
376                is active
377        """
378        raise NotImplementedError()
379
380    def set_drx_on_duration_timer(self, bts_index, timer):
381        """ Sets the amount of PDCCH subframes to wait for data after
382            waking up from a DRX cycle
383
384        Args:
385            bts_index: the base station number
386            timer: Number of PDCCH subframes to wait and check for user data
387                after waking from the DRX cycle
388        """
389        raise NotImplementedError()
390
391    def set_drx_inactivity_timer(self, bts_index, timer):
392        """ Sets the number of PDCCH subframes to wait before entering DRX mode
393
394        Args:
395            bts_index: the base station number
396            timer: The amount of time to wait before entering DRX mode
397        """
398        raise NotImplementedError()
399
400    def set_drx_retransmission_timer(self, bts_index, timer):
401        """ Sets the number of consecutive PDCCH subframes to wait
402        for retransmission
403
404        Args:
405            bts_index: the base station number
406            timer: Number of PDCCH subframes to remain active
407
408        """
409        raise NotImplementedError()
410
411    def set_drx_long_cycle(self, bts_index, cycle):
412        """ Sets the amount of subframes representing a DRX long cycle.
413
414        Args:
415            bts_index: the base station number
416            cycle: The amount of subframes representing one long DRX cycle.
417                One cycle consists of DRX sleep + DRX on duration
418        """
419        raise NotImplementedError()
420
421    def set_drx_long_cycle_offset(self, bts_index, offset):
422        """ Sets the offset used to determine the subframe number
423        to begin the long drx cycle
424
425        Args:
426            bts_index: the base station number
427            offset: Number in range 0 to (long cycle - 1)
428        """
429        raise NotImplementedError()
430
431    def set_apn(self, apn):
432        """ Configures the callbox network Access Point Name.
433
434        Args:
435            apn: the APN name
436        """
437        raise NotImplementedError()
438
439    def set_ip_type(self, ip_type):
440        """ Configures the callbox network IP type.
441
442        Args:
443            ip_type: the network type to use.
444        """
445        raise NotImplementedError()
446
447    def set_mtu(self, mtu):
448        """ Configures the callbox network Maximum Transmission Unit.
449
450        Args:
451            mtu: the MTU size.
452        """
453        raise NotImplementedError()
454
455    def lte_attach_secondary_carriers(self, ue_capability_enquiry):
456        """ Activates the secondary carriers for CA. Requires the DUT to be
457        attached to the primary carrier first.
458
459        Args:
460            ue_capability_enquiry: UE capability enquiry message to be sent to
461        the UE before starting carrier aggregation.
462        """
463        raise NotImplementedError()
464
465    def wait_until_attached(self, timeout=120):
466        """ Waits until the DUT is attached to the primary carrier.
467
468        Args:
469            timeout: after this amount of time the method will raise a
470                CellularSimulatorError exception. Default is 120 seconds.
471        """
472        raise NotImplementedError()
473
474    def wait_until_communication_state(self, timeout=120):
475        """ Waits until the DUT is in Communication state.
476
477        Args:
478            timeout: after this amount of time the method will raise a
479                CellularSimulatorError exception. Default is 120 seconds.
480        """
481        raise NotImplementedError()
482
483    def wait_until_idle_state(self, timeout=120):
484        """ Waits until the DUT is in Idle state.
485
486        Args:
487            timeout: after this amount of time the method will raise a
488                CellularSimulatorError exception. Default is 120 seconds.
489        """
490        raise NotImplementedError()
491
492    def wait_until_quiet(self, timeout=120):
493        """Waits for all pending operations to finish on the simulator.
494
495        Args:
496            timeout: after this amount of time the method will raise a
497                CellularSimulatorError exception. Default is 120 seconds.
498        """
499        raise NotImplementedError()
500
501    def detach(self):
502        """ Turns off all the base stations so the DUT loose connection."""
503        raise NotImplementedError()
504
505    def stop(self):
506        """ Stops current simulation. After calling this method, the simulator
507        will need to be set up again. """
508        raise NotImplementedError()
509
510    def start_data_traffic(self):
511        """ Starts transmitting data from the instrument to the DUT. """
512        raise NotImplementedError()
513
514    def stop_data_traffic(self):
515        """ Stops transmitting data from the instrument to the DUT. """
516        raise NotImplementedError()
517
518    def get_measured_pusch_power(self):
519        """ Queries PUSCH power measured at the callbox.
520
521        Returns:
522            The PUSCH power in the primary input port.
523        """
524        raise NotImplementedError()
525
526    def send_sms(self, message):
527        """ Sends an SMS message to the DUT.
528
529        Args:
530            message: the SMS message to send.
531        """
532        raise NotImplementedError()
533
534
535class CellularSimulatorError(Exception):
536    """ Exceptions thrown when the cellular equipment is unreachable or it
537    returns an error after receiving a command. """
538