1#!/usr/bin/env python3 2# 3# Copyright 2021 - 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. 16 17import acts.controllers.cellular_lib.BaseCellConfig as base_cell 18import acts.controllers.cellular_lib.LteSimulation as lte_sim 19 20 21class NrCellConfig(base_cell.BaseCellConfig): 22 """ NR cell configuration class. 23 24 Attributes: 25 band: an integer indicating the required band number. 26 bandwidth: a integer indicating the required channel bandwidth 27 """ 28 29 PARAM_BAND = "band" 30 PARAM_BW = "bw" 31 PARAM_DL_MCS = "dlmcs" 32 PARAM_DL_RBS = "dl_rbs" 33 PARAM_PADDING = "mac_padding" 34 PARAM_MIMO = "mimo" 35 PARAM_NRARFCN = "nr_arfcn" 36 PARAM_SCHEDULING = "scheduling" 37 PARAM_SCHEDULING_DYNAMIC = "dynamic" 38 PARAM_SCHEDULING_STATIC = "static" 39 PARAM_UL_MCS = "ulmcs" 40 PARAM_UL_RBS = "ul_rbs" 41 PARAM_TA = "tracking_area" 42 PARAM_DRX = "drx" 43 44 PARAM_DISABLE_ALL_UL_SLOTS = "disable_all_ul_slots" 45 PARAM_CONFIG_FLEXIBLE_SLOTS = "config_flexible_slots" 46 47 def __init__(self, log): 48 """ Initialize the base station config by setting all its 49 parameters to None. 50 Args: 51 log: logger object. 52 """ 53 super().__init__(log) 54 self.band = None 55 self.bandwidth = None 56 self.dl_rbs = None 57 self.ul_rbs = None 58 self.dl_mcs = None 59 self.ul_mcs = None 60 self.mac_padding = None 61 self.mimo_mode = None 62 self.nr_arfcn = None 63 self.drx_connected_mode = None 64 self.disable_all_ul_slots = None 65 self.config_flexible_slots = None 66 self.drx_on_duration_timer = None 67 self.drx_inactivity_timer = None 68 self.drx_retransmission_timer_dl = None 69 self.drx_retransmission_timer_ul = None 70 self.drx_long_cycle = None 71 self.harq_rtt_timer_dl = 0 72 self.harq_rtt_timer_ul = 0 73 self.slot_offset = 0 74 75 76 def configure(self, parameters): 77 """ Configures an NR cell using a dictionary of parameters. 78 79 Args: 80 parameters: a configuration dictionary 81 """ 82 if self.PARAM_BAND not in parameters: 83 raise ValueError( 84 "The configuration dictionary must include a key '{}' with " 85 "the required band number.".format(self.PARAM_BAND)) 86 nr_band = parameters[self.PARAM_BAND] 87 if nr_band[0] == 'n': 88 nr_band = nr_band[1:] 89 self.band = nr_band 90 91 if self.PARAM_NRARFCN in parameters: 92 self.nr_arfcn = int(parameters[self.PARAM_NRARFCN]) 93 94 if self.PARAM_BW not in parameters: 95 raise ValueError( 96 "The config dictionary must include parameter {} with an " 97 "int value (to indicate 1.4 MHz use 14).".format( 98 self.PARAM_BW)) 99 bw = float(parameters[self.PARAM_BW]) 100 101 if abs(bw - 14) < 0.00000000001: 102 bw = 1.4 103 104 self.bandwidth = bw 105 106 if self.PARAM_TA in parameters: 107 self.tracking_area = int(parameters[self.PARAM_TA]) 108 else: 109 self.tracking_area = None 110 111 # Setup mimo mode 112 if self.PARAM_MIMO not in parameters: 113 raise ValueError( 114 "The config dictionary must include parameter '{}' with the " 115 "mimo mode.".format(self.PARAM_MIMO)) 116 117 for mimo_mode in lte_sim.MimoMode: 118 if parameters[self.PARAM_MIMO] == mimo_mode.value: 119 self.mimo_mode = mimo_mode 120 break 121 else: 122 raise ValueError("The value of {} must be one of the following:" 123 "1x1, 2x2 or 4x4.".format(self.PARAM_MIMO)) 124 125 if self.PARAM_SCHEDULING not in parameters: 126 self.scheduling_mode = lte_sim.SchedulingMode.STATIC 127 self.log.warning( 128 "The test config does not include the '{}' key. Setting to " 129 "static by default.".format(self.PARAM_SCHEDULING)) 130 elif parameters[ 131 self.PARAM_SCHEDULING] == self.PARAM_SCHEDULING_DYNAMIC: 132 self.scheduling_mode = lte_sim.SchedulingMode.DYNAMIC 133 elif parameters[self.PARAM_SCHEDULING] == self.PARAM_SCHEDULING_STATIC: 134 self.scheduling_mode = lte_sim.SchedulingMode.STATIC 135 else: 136 raise ValueError("Key '{}' must have a value of " 137 "'dynamic' or 'static'.".format( 138 self.PARAM_SCHEDULING)) 139 140 if self.scheduling_mode == lte_sim.SchedulingMode.STATIC: 141 142 if self.PARAM_PADDING not in parameters: 143 self.log.warning( 144 "The '{}' parameter was not set. Enabling MAC padding by " 145 "default.".format(self.PARAM_PADDING)) 146 self.mac_padding = True 147 else: 148 self.mac_padding = parameters[self.PARAM_PADDING] 149 150 if self.PARAM_DL_MCS in parameters: 151 self.dl_mcs = int(parameters[self.PARAM_DL_MCS]) 152 153 if self.PARAM_UL_MCS in parameters: 154 self.ul_mcs = int(parameters[self.PARAM_UL_MCS]) 155 156 # Temproraily setting: set 273 for bandwidth of 100 MHz 157 self.dl_rbs = 273 158 self.ul_rbs = 273 159 160 self.disable_all_ul_slots = parameters.get( 161 self.PARAM_DISABLE_ALL_UL_SLOTS, False) 162 self.config_flexible_slots = parameters.get( 163 self.PARAM_CONFIG_FLEXIBLE_SLOTS, False) 164 165 if self.PARAM_DRX in parameters and len( 166 parameters[self.PARAM_DRX]) >= 6: 167 self.drx_connected_mode = True 168 param_drx = parameters[self.PARAM_DRX] 169 self.drx_on_duration_timer = param_drx[0] 170 self.drx_inactivity_timer = param_drx[1] 171 self.drx_retransmission_timer_dl = param_drx[2] 172 self.drx_retransmission_timer_ul = param_drx[3] 173 self.drx_long_cycle = param_drx[4] 174 try: 175 long_cycle = int(param_drx[4]) 176 long_cycle_offset = int(param_drx[5]) 177 if long_cycle_offset in range(0, long_cycle): 178 self.drx_long_cycle_offset = long_cycle_offset 179 else: 180 self.log.error( 181 ("The cDRX long cycle offset must be in the " 182 "range 0 to (long cycle - 1). Setting " 183 "long cycle offset to 0")) 184 self.drx_long_cycle_offset = 0 185 186 self.harq_rtt_timer_dl = ( 187 int(param_drx[6]) 188 if len(param_drx) >= 7 189 else 0 190 ) 191 self.harq_rtt_timer_ul = ( 192 int(param_drx[7]) 193 if len(param_drx) >= 8 194 else 0 195 ) 196 self.slot_offset = ( 197 int(param_drx[8]) 198 if len(param_drx) >= 9 199 else 0 200 ) 201 202 except ValueError: 203 self.log.error(("cDRX long cycle and long cycle offset " 204 "must be integers. Disabling cDRX mode.")) 205 self.drx_connected_mode = False 206 else: 207 self.log.warning( 208 "DRX mode was not configured properly.\n" 209 "Please provide a list with the following values:\n" 210 "1) DRX on duration timer\n" 211 "2) Inactivity timer\n" 212 "3) Retransmission timer dl\n" 213 "4) Retransmission timer ul\n" 214 "5) Long DRX cycle duration\n" 215 "6) Long DRX cycle offset\n" 216 "7) harq RTT timer dl\n" 217 "8) harq RTT timer ul\n" 218 "9) slot offset\n" 219 "Example: [2, 6, 1, 1, 160, 0, 0, 0, 0].") 220 221 def __str__(self): 222 return str(vars(self)) 223