blob: 5b98efd22d6e2760d2ec51db456b82fb09d66d5b [file] [log] [blame]
Wei-Yu Chenb91af852022-03-15 22:24:49 +08001"""
2Copyright 2020 The Magma Authors.
Wei-Yu Chen49950b92021-11-08 19:19:18 +08003
Wei-Yu Chenb91af852022-03-15 22:24:49 +08004This source code is licensed under the BSD-style license found in the
5LICENSE file in the root directory of this source tree.
6
7Unless required by applicable law or agreed to in writing, software
8distributed under the License is distributed on an "AS IS" BASIS,
9WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10See the License for the specific language governing permissions and
11limitations under the License.
12"""
Wei-Yu Chen49950b92021-11-08 19:19:18 +080013import logging
14from typing import Any, Callable, Dict, List, Optional, Type
15
16from common.service import MagmaService
17from data_models import transform_for_magma
18from data_models.data_model import (
19 DataModel,
20 InvalidTrParamPath,
21 TrParam,
22)
23from data_models.data_model_parameters import (
24 ParameterName,
25 TrParameterType,
26)
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +080027from configuration.service_configs import load_enb_config
Wei-Yu Chen49950b92021-11-08 19:19:18 +080028from device_config.configuration_init import build_desired_config
29from device_config.enodeb_config_postprocessor import EnodebConfigurationPostProcessor
30from device_config.enodeb_configuration import EnodebConfiguration
31from devices.device_utils import EnodebDeviceName
32from logger import EnodebdLogger
33from state_machines.acs_state_utils import (
34 get_all_objects_to_add,
35 get_all_objects_to_delete,
36 get_all_param_values_to_set,
37 get_params_to_get,
38 parse_get_parameter_values_response,
39)
40from state_machines.enb_acs import EnodebAcsStateMachine
41from state_machines.enb_acs_impl import BasicEnodebAcsStateMachine
42from state_machines.enb_acs_states import (
43 AcsMsgAndTransition,
44 AcsReadMsgResult,
45 AddObjectsState,
46 DeleteObjectsState,
47 EnbSendRebootState,
48 EndSessionState,
49 EnodebAcsState,
50 ErrorState,
51 GetParametersState,
52 SetParameterValuesState,
53 WaitGetParametersState,
54 WaitInformMRebootState,
55 WaitInformState,
56 WaitRebootResponseState,
57 WaitSetParameterValuesState,
58)
59from tr069 import models
60
61
Wei-Yu Chen678f0a52021-12-21 13:50:52 +080062FAPSERVICE_PATH = "Device.Services.FAPService.1."
63FAP_CONTROL = FAPSERVICE_PATH + "FAPControl."
64
65
66class FreedomFiOneHandler(BasicEnodebAcsStateMachine):
67 def __init__(self, service: MagmaService,) -> None:
68 self._state_map = {}
69 super().__init__(service=service, use_param_key=True)
70
71 def reboot_asap(self) -> None:
72 self.transition("reboot")
73
74 def is_enodeb_connected(self) -> bool:
75 return not isinstance(self.state, WaitInformState)
76
77 def _init_state_map(self) -> None:
78 self._state_map = {
79 # Inform comes in -> Respond with InformResponse
80 "wait_inform": WaitInformState(self, when_done="get_rpc_methods"),
81 # If first inform after boot -> GetRpc request comes in, if not
82 # empty request comes in => Transition to get_transient_params
83 "get_rpc_methods": FreedomFiOneGetInitState(
84 self, when_done="get_transient_params",
85 ),
86 # Read transient readonly params.
87 "get_transient_params": FreedomFiOneSendGetTransientParametersState(
Wei-Yu Chenb91af852022-03-15 22:24:49 +080088 self, when_done="get_params",
Wei-Yu Chen678f0a52021-12-21 13:50:52 +080089 ),
90 "get_params": FreedomFiOneGetObjectParametersState(
91 self,
92 when_delete="delete_objs",
93 when_add="add_objs",
94 when_set="set_params",
95 when_skip="end_session",
96 ),
97 "delete_objs": DeleteObjectsState(
98 self, when_add="add_objs", when_skip="set_params",
99 ),
100 "add_objs": AddObjectsState(self, when_done="set_params"),
101 "set_params": SetParameterValuesState(self, when_done="wait_set_params",),
102 "wait_set_params": WaitSetParameterValuesState(
103 self,
104 when_done="check_get_params",
105 when_apply_invasive="check_get_params",
106 status_non_zero_allowed=True,
107 ),
108 "check_get_params": GetParametersState(
109 self, when_done="check_wait_get_params", request_all_params=True,
110 ),
111 "check_wait_get_params": WaitGetParametersState(
112 self, when_done="end_session",
113 ),
114 "end_session": EndSessionState(self),
115 # These states are only entered through manual user intervention
116 "reboot": EnbSendRebootState(self, when_done="wait_reboot"),
117 "wait_reboot": WaitRebootResponseState(
118 self, when_done="wait_post_reboot_inform",
119 ),
120 "wait_post_reboot_inform": WaitInformMRebootState(
121 self, when_done="wait_empty", when_timeout="wait_inform",
122 ),
123 # The states below are entered when an unexpected message type is
124 # received
125 "unexpected_fault": ErrorState(
126 self, inform_transition_target="wait_inform",
127 ),
128 }
129
130 @property
131 def device_name(self) -> str:
132 return EnodebDeviceName.FREEDOMFI_ONE
133
134 @property
135 def data_model_class(self) -> Type[DataModel]:
136 return FreedomFiOneTrDataModel
137
138 @property
139 def config_postprocessor(self) -> EnodebConfigurationPostProcessor:
140 return FreedomFiOneConfigurationInitializer(self)
141
142 @property
143 def state_map(self) -> Dict[str, EnodebAcsState]:
144 return self._state_map
145
146 @property
147 def disconnected_state_name(self) -> str:
148 return "wait_inform"
149
150 @property
151 def unexpected_fault_state_name(self) -> str:
152 return "unexpected_fault"
153
154
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800155class SASParameters:
156 """ Class modeling the SAS parameters and their TR path"""
157
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800158 # For CBRS radios we set this to the limit and the SAS can reduce the
159 # power if needed.
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800160
161 SAS_PARAMETERS = {
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800162 ParameterName.SAS_ENABLE: TrParam(
163 FAP_CONTROL + "LTE.X_SCM_SAS.Enable",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800164 is_invasive=False,
165 type=TrParameterType.BOOLEAN,
166 is_optional=False,
167 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800168 ParameterName.SAS_SERVER_URL: TrParam(
169 FAP_CONTROL + "LTE.X_SCM_SAS.Server",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800170 is_invasive=False,
171 type=TrParameterType.STRING,
172 is_optional=False,
173 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800174 ParameterName.SAS_UID: TrParam(
175 FAP_CONTROL + "LTE.X_SCM_SAS.UserContactInformation",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800176 is_invasive=False,
177 type=TrParameterType.STRING,
178 is_optional=False,
179 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800180 ParameterName.SAS_CATEGORY: TrParam(
181 FAP_CONTROL + "LTE.X_SCM_SAS.Category",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800182 is_invasive=False,
183 type=TrParameterType.STRING,
184 is_optional=False,
185 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800186 ParameterName.SAS_CHANNEL_TYPE: TrParam(
187 FAP_CONTROL + "LTE.X_SCM_SAS.ProtectionLevel",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800188 is_invasive=False,
189 type=TrParameterType.STRING,
190 is_optional=False,
191 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800192 ParameterName.SAS_CERT_SUBJECT: TrParam(
193 FAP_CONTROL + "LTE.X_SCM_SAS.CertSubject",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800194 is_invasive=False,
195 type=TrParameterType.STRING,
196 is_optional=False,
197 ),
198 # SAS_IC_GROUP_ID: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800199 # FAP_CONTROL + 'LTE.X_SCM_SAS.ICGGroupId', is_invasive=False,
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800200 # type=TrParameterType.STRING, False),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800201 ParameterName.SAS_LOCATION: TrParam(
202 FAP_CONTROL + "LTE.X_SCM_SAS.Location",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800203 is_invasive=False,
204 type=TrParameterType.STRING,
205 is_optional=False,
206 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800207 ParameterName.SAS_HEIGHT_TYPE: TrParam(
208 FAP_CONTROL + "LTE.X_SCM_SAS.HeightType",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800209 is_invasive=False,
210 type=TrParameterType.STRING,
211 is_optional=False,
212 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800213 ParameterName.SAS_CPI_ENABLE: TrParam(
214 FAP_CONTROL + "LTE.X_SCM_SAS.CPIEnable",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800215 is_invasive=False,
216 type=TrParameterType.BOOLEAN,
217 is_optional=False,
218 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800219 ParameterName.SAS_CPI_IPE: TrParam(
220 FAP_CONTROL + "LTE.X_SCM_SAS.CPIInstallParamSuppliedEnable",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800221 is_invasive=False,
222 type=TrParameterType.BOOLEAN,
223 is_optional=False,
224 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800225 ParameterName.SAS_FCCID: TrParam(
226 FAP_CONTROL + "LTE.X_SCM_SAS.FCCIdentificationNumber",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800227 is_invasive=False,
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800228 type=TrParameterType.STRING,
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800229 is_optional=False,
230 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800231 ParameterName.SAS_MEAS_CAPS: TrParam(
232 FAP_CONTROL + "LTE.X_SCM_SAS.MeasCapability",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800233 is_invasive=False,
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800234 type=TrParameterType.STRING,
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800235 is_optional=False,
236 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800237 ParameterName.SAS_MANU_ENABLE: TrParam(
238 FAP_CONTROL + "LTE.X_SCM_SAS.ManufacturerPrefixEnable",
239 is_invasive=False,
240 type=TrParameterType.BOOLEAN,
241 is_optional=False,
242 ),
243 ParameterName.SAS_CPI_NAME: TrParam(
244 FAP_CONTROL + "LTE.X_SCM_SAS.CPIName",
245 is_invasive=False,
246 type=TrParameterType.STRING,
247 is_optional=False,
248 ),
249 ParameterName.SAS_CPI_ID: TrParam(
250 FAP_CONTROL + "LTE.X_SCM_SAS.CPIId",
251 is_invasive=False,
252 type=TrParameterType.STRING,
253 is_optional=False,
254 ),
255 ParameterName.SAS_ANTA_AZIMUTH: TrParam(
256 FAP_CONTROL + "LTE.X_SCM_SAS.AntennaAzimuth",
257 is_invasive=False,
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800258 type=TrParameterType.INT,
259 is_optional=False,
260 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800261 ParameterName.SAS_ANTA_DOWNTILT: TrParam(
262 FAP_CONTROL + "LTE.X_SCM_SAS.AntennaDowntilt",
263 is_invasive=False,
264 type=TrParameterType.INT,
265 is_optional=False,
266 ),
267 ParameterName.SAS_ANTA_GAIN: TrParam(
268 FAP_CONTROL + "LTE.X_SCM_SAS.AntennaGain",
269 is_invasive=False,
270 type=TrParameterType.INT,
271 is_optional=False,
272 ),
273 ParameterName.SAS_ANTA_BEAMWIDTH: TrParam(
274 FAP_CONTROL + "LTE.X_SCM_SAS.AntennaBeamwidth",
275 is_invasive=False,
276 type=TrParameterType.INT,
277 is_optional=False,
278 ),
279 ParameterName.SAS_CPI_DATA: TrParam(
280 FAP_CONTROL + "LTE.X_SCM_SAS.CPISignatureData",
281 is_invasive=False,
282 type=TrParameterType.STRING,
283 is_optional=False,
284 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800285 }
286
287
288class StatusParameters:
289 """
290 Stateful class that converts eNB status to Magma understood status.
291 FreedomFiOne has many status params that interact with each other.
292 This class maintains the business logic of parsing these status params
293 and converting it to Magma understood fields.
294 """
295
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800296 # Status parameters
297 DEFAULT_GW = "defaultGW"
298 SYNC_STATUS = "syncStatus"
299 SAS_STATUS = "sasStatus"
300 ENB_STATUS = "enbStatus"
301 GPS_SCAN_STATUS = "gpsScanStatus"
302
303 STATUS_PARAMETERS = {
304 # Status nodes
305 DEFAULT_GW: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800306 "Device.X_SCM_DeviceFeature.X_SCM_NEStatus.X_SCM_DEFGW_Status",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800307 is_invasive=False,
308 type=TrParameterType.STRING,
309 is_optional=False,
310 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800311 SAS_STATUS: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800312 "Device.Services.FAPService.1.FAPControl.LTE.X_SCM_SAS.State",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800313 is_invasive=False,
314 type=TrParameterType.STRING,
315 is_optional=False,
316 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800317 GPS_SCAN_STATUS: TrParam(
318 "Device.FAP.GPS.ScanStatus",
319 is_invasive=False,
320 type=TrParameterType.STRING,
321 is_optional=False,
322 ),
323 ParameterName.GPS_LAT: TrParam(
324 "Device.FAP.GPS.LockedLatitude",
325 is_invasive=False,
326 type=TrParameterType.STRING,
327 is_optional=False,
328 ),
329 ParameterName.GPS_LONG: TrParam(
330 "Device.FAP.GPS.LockedLongitude",
331 is_invasive=False,
332 type=TrParameterType.STRING,
333 is_optional=False,
334 ),
335 }
336
337 # Derived status params that don't have tr69 representation.
338 DERIVED_STATUS_PARAMETERS = {
339 ParameterName.RF_TX_STATUS: TrParam(
340 InvalidTrParamPath,
341 is_invasive=False,
342 type=TrParameterType.BOOLEAN,
343 is_optional=False,
344 ),
345 ParameterName.GPS_STATUS: TrParam(
346 InvalidTrParamPath,
347 is_invasive=False,
348 type=TrParameterType.BOOLEAN,
349 is_optional=False,
350 ),
351 ParameterName.PTP_STATUS: TrParam(
352 InvalidTrParamPath,
353 is_invasive=False,
354 type=TrParameterType.BOOLEAN,
355 is_optional=False,
356 ),
357 ParameterName.MME_STATUS: TrParam(
358 InvalidTrParamPath,
359 is_invasive=False,
360 type=TrParameterType.BOOLEAN,
361 is_optional=False,
362 ),
363 ParameterName.OP_STATE: TrParam(
364 InvalidTrParamPath,
365 is_invasive=False,
366 type=TrParameterType.BOOLEAN,
367 is_optional=False,
368 ),
369 }
370
371 @classmethod
372 def set_magma_device_cfg(
373 cls, name_to_val: Dict, device_cfg: EnodebConfiguration,
374 ):
375 """
376 Convert FreedomFiOne name_to_val representation to magma device_cfg
377 """
378 success_str = "SUCCESS" # String constant returned by radio
379 insync_str = "INSYNC"
380
381 if (
382 name_to_val.get(cls.DEFAULT_GW)
383 and name_to_val[cls.DEFAULT_GW].upper() != success_str
384 ):
385 # Nothing will proceed if the eNB doesn't have an IP on the WAN
386 serial_num = "unknown"
387 if device_cfg.has_parameter(ParameterName.SERIAL_NUMBER):
388 serial_num = device_cfg.get_parameter(ParameterName.SERIAL_NUMBER,)
389 EnodebdLogger.error(
390 "Radio with serial number %s doesn't have IP address " "on WAN",
391 serial_num,
392 )
393 device_cfg.set_parameter(
394 param_name=ParameterName.RF_TX_STATUS, value=False,
395 )
396 device_cfg.set_parameter(
397 param_name=ParameterName.GPS_STATUS, value=False,
398 )
399 device_cfg.set_parameter(
400 param_name=ParameterName.PTP_STATUS, value=False,
401 )
402 device_cfg.set_parameter(
403 param_name=ParameterName.MME_STATUS, value=False,
404 )
405 device_cfg.set_parameter(
406 param_name=ParameterName.OP_STATE, value=False,
407 )
408 return
409
410 if (
411 name_to_val.get(cls.SAS_STATUS)
412 and name_to_val[cls.SAS_STATUS].upper() == success_str
413 ):
414 device_cfg.set_parameter(
415 param_name=ParameterName.RF_TX_STATUS, value=True,
416 )
417 else:
418 # No sas grant so not transmitting. There is no explicit node for Tx
419 # in FreedomFiOne
420 device_cfg.set_parameter(
421 param_name=ParameterName.RF_TX_STATUS, value=False,
422 )
423
424 if (
425 name_to_val.get(cls.GPS_SCAN_STATUS)
426 and name_to_val[cls.GPS_SCAN_STATUS].upper() == success_str
427 ):
428 device_cfg.set_parameter(
429 param_name=ParameterName.GPS_STATUS, value=True,
430 )
431 # Time comes through GPS so can only be insync with GPS is
432 # in sync, we use PTP_STATUS field to overload timer is in Sync.
433 if (
434 name_to_val.get(cls.SYNC_STATUS)
435 and name_to_val[cls.SYNC_STATUS].upper() == insync_str
436 ):
437 device_cfg.set_parameter(
438 param_name=ParameterName.PTP_STATUS, value=True,
439 )
440 else:
441 device_cfg.set_parameter(
442 param_name=ParameterName.PTP_STATUS, value=False,
443 )
444 else:
445 device_cfg.set_parameter(
446 param_name=ParameterName.GPS_STATUS, value=False,
447 )
448 device_cfg.set_parameter(
449 param_name=ParameterName.PTP_STATUS, value=False,
450 )
451
452 if (
453 name_to_val.get(cls.DEFAULT_GW)
454 and name_to_val[cls.DEFAULT_GW].upper() == success_str
455 ):
456 device_cfg.set_parameter(
457 param_name=ParameterName.MME_STATUS, value=True,
458 )
459 else:
460 device_cfg.set_parameter(
461 param_name=ParameterName.MME_STATUS, value=False,
462 )
463
464 if (
465 name_to_val.get(cls.ENB_STATUS)
466 and name_to_val[cls.ENB_STATUS].upper() == success_str
467 ):
468 device_cfg.set_parameter(
469 param_name=ParameterName.OP_STATE, value=True,
470 )
471 else:
472 device_cfg.set_parameter(
473 param_name=ParameterName.OP_STATE, value=False,
474 )
475
476 pass_through_params = [ParameterName.GPS_LAT, ParameterName.GPS_LONG]
477 for name in pass_through_params:
478 device_cfg.set_parameter(name, name_to_val[name])
479
480
481class FreedomFiOneMiscParameters:
482 """
483 Default set of parameters that enable carrier aggregation and other
484 miscellaneous properties
485 """
486
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800487 MISC_PARAMETERS = {
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800488 ParameterName.CARRIER_AGG_ENABLE: TrParam(
489 FAP_CONTROL + "LTE.X_SCM_RRMConfig.X_SCM_CA_Enable",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800490 is_invasive=False,
491 type=TrParameterType.BOOLEAN,
492 is_optional=False,
493 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800494 ParameterName.CARRIER_NUMBER: TrParam(
495 FAP_CONTROL + "LTE.X_SCM_RRMConfig.X_SCM_Cell_Number",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800496 is_invasive=False,
497 type=TrParameterType.INT,
498 is_optional=False,
499 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800500 ParameterName.CONTIGUOUS_CC: TrParam(
501 FAP_CONTROL + "LTE.X_SCM_RRMConfig.X_SCM_CELL_Freq_Contiguous",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800502 is_invasive=False,
503 type=TrParameterType.INT,
504 is_optional=False,
505 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800506 ParameterName.PRIM_SOURCE: TrParam(
507 FAPSERVICE_PATH + "REM.X_SCM_tfcsManagerConfig.primSrc",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800508 is_invasive=False,
509 type=TrParameterType.STRING,
510 is_optional=False,
511 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800512 ParameterName.ENABLE_CWMP: TrParam(
513 "Device.ManagementServer.EnableCWMP",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800514 is_invasive=False,
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800515 type=TrParameterType.BOOLEAN,
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800516 is_optional=False,
517 ),
518 }
519
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800520
521class FreedomFiOneTrDataModel(DataModel):
522 """
523 Class to represent relevant data model parameters from TR-196/TR-098.
524 This class is effectively read-only.
525
526 These models have these idiosyncrasies (on account of running TR098):
527
528 - Parameter content root is different (InternetGatewayDevice)
529 - GetParameter queries with a wildcard e.g. InternetGatewayDevice. do
530 not respond with the full tree (we have to query all parameters)
531 - MME status is not exposed - we assume the MME is connected if
532 the eNodeB is transmitting (OpState=true)
533 - Parameters such as band capability/duplex config
534 are rooted under `boardconf.` and not the device config root
535 - Num PLMNs is not reported by these units
536 """
537
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800538 PARAMETERS = {
539 # Top-level objects
540 ParameterName.DEVICE: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800541 "Device.",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800542 is_invasive=False,
543 type=TrParameterType.OBJECT,
544 is_optional=False,
545 ),
546 ParameterName.FAP_SERVICE: TrParam(
547 FAP_CONTROL,
548 is_invasive=False,
549 type=TrParameterType.OBJECT,
550 is_optional=False,
551 ),
552 # Device info
Wei-Yu Chenb91af852022-03-15 22:24:49 +0800553 ParameterName.SW_VERSION: TrParam(
554 "Device.DeviceInfo.SoftwareVersion",
555 is_invasive=False,
556 type=TrParameterType.STRING,
557 is_optional=False,
558 ),
559 ParameterName.SERIAL_NUMBER: TrParam(
560 "Device.DeviceInfo.SerialNumber",
561 is_invasive=False,
562 type=TrParameterType.STRING,
563 is_optional=False,
564 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800565 ParameterName.IP_ADDRESS: TrParam(
566 "Device.IP.Interface.1.IPv4Address.1.IPAddress",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800567 is_invasive=False,
568 type=TrParameterType.STRING,
569 is_optional=False,
570 ),
571 # RF-related parameters
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800572 ParameterName.FREQ_BAND_1: TrParam(
573 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.FreqBandIndicator",
574 is_invasive=False,
575 type=TrParameterType.UNSIGNED_INT,
576 is_optional=False,
577 ),
578 ParameterName.FREQ_BAND_2: TrParam(
579 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_FreqBandIndicator2",
580 is_invasive=False,
581 type=TrParameterType.UNSIGNED_INT,
582 is_optional=False,
583 ),
584 ParameterName.FREQ_BAND_LIST: TrParam(
585 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_FreqBandIndicatorConfigList",
586 is_invasive=False,
587 type=TrParameterType.STRING,
588 is_optional=False,
589 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800590 ParameterName.EARFCNDL: TrParam(
591 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.EARFCNDL",
592 is_invasive=False,
593 type=TrParameterType.INT,
594 is_optional=False,
595 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800596 ParameterName.EARFCNUL: TrParam(
597 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.EARFCNUL",
598 is_invasive=False,
599 type=TrParameterType.INT,
600 is_optional=False,
601 ),
602 ParameterName.EARFCNDL2: TrParam(
603 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_EARFCNDL2",
604 is_invasive=False,
605 type=TrParameterType.INT,
606 is_optional=False,
607 ),
608 ParameterName.EARFCNUL2: TrParam(
609 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_EARFCNUL2",
610 is_invasive=False,
611 type=TrParameterType.INT,
612 is_optional=False,
613 ),
614 ParameterName.EARFCNDL_LIST: TrParam(
615 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_EARFCNDLConfigList",
616 is_invasive=False,
617 type=TrParameterType.STRING,
618 is_optional=False,
619 ),
620 ParameterName.EARFCNUL_LIST: TrParam(
621 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_EARFCNULConfigList",
622 is_invasive=False,
623 type=TrParameterType.STRING,
624 is_optional=False,
625 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800626 ParameterName.DL_BANDWIDTH: TrParam(
627 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.DLBandwidth",
628 is_invasive=False,
629 type=TrParameterType.STRING,
630 is_optional=False,
631 ),
632 ParameterName.UL_BANDWIDTH: TrParam(
633 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.ULBandwidth",
634 is_invasive=False,
635 type=TrParameterType.STRING,
636 is_optional=False,
637 ),
Wei-Yu Chen8d064162022-05-27 21:06:55 +0800638 ParameterName.PCI1: TrParam(
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800639 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.PhyCellID",
640 is_invasive=False,
641 type=TrParameterType.STRING,
642 is_optional=False,
643 ),
644 ParameterName.SUBFRAME_ASSIGNMENT: TrParam(
645 FAPSERVICE_PATH + "CellConfig.LTE.RAN.PHY.TDDFrame.SubFrameAssignment",
646 is_invasive=False,
Wei-Yu Chenb91af852022-03-15 22:24:49 +0800647 type=TrParameterType.BOOLEAN,
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800648 is_optional=False,
649 ),
650 ParameterName.SPECIAL_SUBFRAME_PATTERN: TrParam(
651 FAPSERVICE_PATH + "CellConfig.LTE.RAN.PHY.TDDFrame.SpecialSubframePatterns",
652 is_invasive=False,
653 type=TrParameterType.INT,
654 is_optional=False,
655 ),
656 ParameterName.CELL_ID: TrParam(
657 FAPSERVICE_PATH + "CellConfig.LTE.RAN.Common.CellIdentity",
658 is_invasive=False,
659 type=TrParameterType.UNSIGNED_INT,
660 is_optional=False,
661 ),
662 # Readonly LTE state
663 ParameterName.ADMIN_STATE: TrParam(
664 FAP_CONTROL + "LTE.AdminState",
665 is_invasive=False,
666 type=TrParameterType.BOOLEAN,
667 is_optional=False,
668 ),
669 ParameterName.GPS_ENABLE: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800670 "Device.FAP.GPS.ScanOnBoot",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800671 is_invasive=False,
672 type=TrParameterType.BOOLEAN,
673 is_optional=False,
674 ),
675 # Core network parameters
Wei-Yu Chen8d064162022-05-27 21:06:55 +0800676 ParameterName.MME_ADDRESS: TrParam(
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800677 FAP_CONTROL + "LTE.Gateway.S1SigLinkServerList",
678 is_invasive=False,
679 type=TrParameterType.STRING,
680 is_optional=False,
681 ),
682 ParameterName.MME_PORT: TrParam(
683 FAP_CONTROL + "LTE.Gateway.S1SigLinkPort",
684 is_invasive=False,
685 type=TrParameterType.INT,
686 is_optional=False,
687 ),
Wei-Yu Chen8d064162022-05-27 21:06:55 +0800688 ParameterName.TAC1: TrParam(
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800689 FAPSERVICE_PATH + "CellConfig.LTE.EPC.TAC",
690 is_invasive=False,
691 type=TrParameterType.INT,
692 is_optional=False,
693 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800694 ParameterName.TAC2: TrParam(
695 FAPSERVICE_PATH + "CellConfig.LTE.EPC.X_SCM_TAC2",
696 is_invasive=False,
697 type=TrParameterType.INT,
698 is_optional=False,
699 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800700 # Management server parameters
701 ParameterName.PERIODIC_INFORM_ENABLE: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800702 "Device.ManagementServer.PeriodicInformEnable",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800703 is_invasive=False,
704 type=TrParameterType.BOOLEAN,
705 is_optional=False,
706 ),
707 ParameterName.PERIODIC_INFORM_INTERVAL: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800708 "Device.ManagementServer.PeriodicInformInterval",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800709 is_invasive=False,
710 type=TrParameterType.INT,
711 is_optional=False,
712 ),
713 # Performance management parameters
714 ParameterName.PERF_MGMT_ENABLE: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800715 "Device.FAP.PerfMgmt.Config.1.Enable",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800716 is_invasive=False,
717 type=TrParameterType.BOOLEAN,
718 is_optional=False,
719 ),
720 ParameterName.PERF_MGMT_UPLOAD_INTERVAL: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800721 "Device.FAP.PerfMgmt.Config.1.PeriodicUploadInterval",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800722 is_invasive=False,
723 type=TrParameterType.INT,
724 is_optional=False,
725 ),
726 ParameterName.PERF_MGMT_UPLOAD_URL: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800727 "Device.FAP.PerfMgmt.Config.1.URL",
728 is_invasive=False,
729 type=TrParameterType.STRING,
730 is_optional=False,
731 ),
732 ParameterName.TX_POWER: TrParam(
733 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_TxPowerConfig",
734 is_invasive=True,
735 type=TrParameterType.INT,
736 is_optional=False,
737 ),
738 ParameterName.TUNNEL_TYPE: TrParam(
739 FAPSERVICE_PATH + "CellConfig.LTE.Tunnel.1.TunnelRef",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800740 is_invasive=False,
741 type=TrParameterType.STRING,
742 is_optional=False,
743 ),
744 }
745 TRANSFORMS_FOR_ENB = {}
746 NUM_PLMNS_IN_CONFIG = 1
747 for i in range(1, NUM_PLMNS_IN_CONFIG + 1):
748 PARAMETERS[ParameterName.PLMN_N % i] = TrParam(
749 FAPSERVICE_PATH + "CellConfig.LTE.EPC.PLMNList.%d." % i,
750 is_invasive=False,
751 type=TrParameterType.STRING,
752 is_optional=False,
753 )
754 PARAMETERS[ParameterName.PLMN_N_CELL_RESERVED % i] = TrParam(
755 FAPSERVICE_PATH
756 + "CellConfig.LTE.EPC.PLMNList.%d.CellReservedForOperatorUse" % i,
757 is_invasive=False,
758 type=TrParameterType.BOOLEAN,
759 is_optional=False,
760 )
761 PARAMETERS[ParameterName.PLMN_N_ENABLE % i] = TrParam(
762 FAPSERVICE_PATH + "CellConfig.LTE.EPC.PLMNList.%d.Enable" % i,
763 is_invasive=False,
764 type=TrParameterType.BOOLEAN,
765 is_optional=False,
766 )
767 PARAMETERS[ParameterName.PLMN_N_PRIMARY % i] = TrParam(
768 FAPSERVICE_PATH + "CellConfig.LTE.EPC.PLMNList.%d.IsPrimary" % i,
769 is_invasive=False,
770 type=TrParameterType.BOOLEAN,
771 is_optional=False,
772 )
773 PARAMETERS[ParameterName.PLMN_N_PLMNID % i] = TrParam(
774 FAPSERVICE_PATH + "CellConfig.LTE.EPC.PLMNList.%d.PLMNID" % i,
775 is_invasive=False,
776 type=TrParameterType.STRING,
777 is_optional=False,
778 )
779
780 PARAMETERS.update(SASParameters.SAS_PARAMETERS)
781 PARAMETERS.update(FreedomFiOneMiscParameters.MISC_PARAMETERS)
782 PARAMETERS.update(StatusParameters.STATUS_PARAMETERS)
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800783 PARAMETERS.update(StatusParameters.DERIVED_STATUS_PARAMETERS)
784
785 TRANSFORMS_FOR_MAGMA = {
786 # We don't set these parameters
787 ParameterName.BAND_CAPABILITY: transform_for_magma.band_capability,
788 ParameterName.DUPLEX_MODE_CAPABILITY: transform_for_magma.duplex_mode,
789 }
790
791 @classmethod
792 def get_parameter(cls, param_name: ParameterName) -> Optional[TrParam]:
793 return cls.PARAMETERS.get(param_name)
794
795 @classmethod
796 def _get_magma_transforms(cls,) -> Dict[ParameterName, Callable[[Any], Any]]:
797 return cls.TRANSFORMS_FOR_MAGMA
798
799 @classmethod
800 def _get_enb_transforms(cls) -> Dict[ParameterName, Callable[[Any], Any]]:
801 return cls.TRANSFORMS_FOR_ENB
802
803 @classmethod
804 def get_load_parameters(cls) -> List[ParameterName]:
805 """
806 Load all the parameters instead of a subset.
807 """
808 return list(cls.PARAMETERS.keys())
809
810 @classmethod
811 def get_num_plmns(cls) -> int:
812 return cls.NUM_PLMNS_IN_CONFIG
813
814 @classmethod
815 def get_parameter_names(cls) -> List[ParameterName]:
816 excluded_params = [
817 str(ParameterName.DEVICE),
818 str(ParameterName.FAP_SERVICE),
819 ]
820 names = list(
821 filter(
822 lambda x: (not str(x).startswith("PLMN"))
823 and (str(x) not in excluded_params),
824 cls.PARAMETERS.keys(),
825 ),
826 )
827 return names
828
829 @classmethod
830 def get_numbered_param_names(cls,) -> Dict[ParameterName, List[ParameterName]]:
831 names = {}
832 for i in range(1, cls.NUM_PLMNS_IN_CONFIG + 1):
833 params = [
834 ParameterName.PLMN_N_CELL_RESERVED % i,
835 ParameterName.PLMN_N_ENABLE % i,
836 ParameterName.PLMN_N_PRIMARY % i,
837 ParameterName.PLMN_N_PLMNID % i,
838 ]
839 names[ParameterName.PLMN_N % i] = params
840
841 return names
842
843 @classmethod
844 def get_sas_param_names(cls) -> List[ParameterName]:
845 return SASParameters.SAS_PARAMETERS.keys()
846
847
848class FreedomFiOneConfigurationInitializer(EnodebConfigurationPostProcessor):
849 """
850 Class to add the sas related parameters to the desired config.
851 """
852
853 SAS_KEY = "sas"
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800854
855 def __init__(self, acs: EnodebAcsStateMachine):
856 super().__init__()
857 self.acs = acs
858
859 def postprocess(
Wei-Yu Chen8d064162022-05-27 21:06:55 +0800860 self, desired_cfg: EnodebConfiguration,
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800861 ) -> None:
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800862 # Bump up the parameter key version
863 self.acs.parameter_version_inc()
864
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +0800865 # Load eNB customized configuration from "./magma_config/serial_number/"
866 # and configure each connected eNB based on serial number
867 enbcfg = load_enb_config()
868 sn = self.acs.get_parameter(ParameterName.SERIAL_NUMBER)
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800869
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +0800870 for name, val in enbcfg.get(sn, {}).items():
871 # The SAS configuration for eNodeB
872 if name in ["sas", "cell"]:
873 for subname, subval in val.items():
874 print("Config %s updated to: %s" % (subname, subval))
875 desired_cfg.set_parameter(subname, subval)
876
877 print(desired_cfg)
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800878
879
880class FreedomFiOneSendGetTransientParametersState(EnodebAcsState):
881 """
882 Periodically read eNodeB status. Note: keep frequency low to avoid
883 backing up large numbers of read operations if enodebd is busy.
884 Some eNB parameters are read only and updated by the eNB itself.
885 """
886
Wei-Yu Chenb91af852022-03-15 22:24:49 +0800887 def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800888 super().__init__()
889 self.acs = acs
890 self.done_transition = when_done
891
892 def get_msg(self, message: Any) -> AcsMsgAndTransition:
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +0800893
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800894 request = models.GetParameterValues()
895 request.ParameterNames = models.ParameterNames()
896 request.ParameterNames.string = []
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +0800897
Wei-Yu Chenb91af852022-03-15 22:24:49 +0800898 # request = models.GetParameterNames()
899 # request.ParameterPath = "Device."
900 # request.NextLevel = False
901
902 # Get the status parameters which was defined in Line 171
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800903 for _, tr_param in StatusParameters.STATUS_PARAMETERS.items():
904 path = tr_param.path
905 request.ParameterNames.string.append(path)
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +0800906
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800907 request.ParameterNames.arrayType = "xsd:string[%d]" % len(
908 request.ParameterNames.string
909 )
910
911 return AcsMsgAndTransition(msg=request, next_state=None)
912
913 def read_msg(self, message: Any) -> AcsReadMsgResult:
914
915 if not isinstance(message, models.GetParameterValuesResponse):
916 return AcsReadMsgResult(msg_handled=False, next_state=None)
917 # Current values of the fetched parameters
918 name_to_val = parse_get_parameter_values_response(self.acs.data_model, message,)
919 EnodebdLogger.debug("Received Parameters: %s", str(name_to_val))
920
921 # Update device configuration
922 StatusParameters.set_magma_device_cfg(
923 name_to_val, self.acs.device_cfg,
924 )
925
Wei-Yu Chenb91af852022-03-15 22:24:49 +0800926 return AcsReadMsgResult(msg_handled=True, next_state=self.done_transition,)
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800927
928 def state_description(self) -> str:
929 return "Getting transient read-only parameters"
930
931
932class FreedomFiOneGetInitState(EnodebAcsState):
933 """
934 After the first Inform message the following can happen:
935 1 - eNB can try to learn the RPC method of the ACS, reply back with the
936 RPC response (happens right after boot)
937 2 - eNB can send an empty message -> This means that the eNB is already
938 provisioned so transition to next state. Only transition to next state
939 after this message.
940 3 - Some other method call that we don't care about so ignore.
941 expected that the eNB -> This is an unhandled state so unlikely
942 """
943
944 def __init__(self, acs: EnodebAcsStateMachine, when_done):
945 super().__init__()
946 self.acs = acs
947 self.done_transition = when_done
948 self._is_rpc_request = False
949
950 def get_msg(self, message: Any) -> AcsMsgAndTransition:
951 """
952 Return empty message response if care about this
953 message type otherwise return empty RPC methods response.
954 """
955 if not self._is_rpc_request:
956 resp = models.DummyInput()
957 return AcsMsgAndTransition(msg=resp, next_state=None)
958
959 resp = models.GetRPCMethodsResponse()
960 resp.MethodList = models.MethodList()
961 RPC_METHODS = ["Inform", "GetRPCMethods", "TransferComplete"]
962 resp.MethodList.arrayType = "xsd:string[%d]" % len(RPC_METHODS)
963 resp.MethodList.string = RPC_METHODS
964 # Don't transition to next state wait for the empty HTTP post
965 return AcsMsgAndTransition(msg=resp, next_state=None)
966
967 def read_msg(self, message: Any) -> AcsReadMsgResult:
968 # If this is a regular Inform, not after a reboot we'll get an empty
969 # message, in this case transition to the next state. We consider
970 # this phase as "initialized"
971 if isinstance(message, models.DummyInput):
972 return AcsReadMsgResult(msg_handled=True, next_state=self.done_transition,)
973 if not isinstance(message, models.GetRPCMethods):
974 # Unexpected, just don't die, ignore message.
975 logging.error("Ignoring message %s", str(type(message)))
976 # Set this so get_msg will return an empty message
977 self._is_rpc_request = False
978 else:
979 # Return a valid RPC response
980 self._is_rpc_request = True
981 return AcsReadMsgResult(msg_handled=True, next_state=None)
982
983 def state_description(self) -> str:
984 return "Initializing the post boot sequence for eNB"
985
986
987class FreedomFiOneGetObjectParametersState(EnodebAcsState):
988 """
989 Get information on parameters belonging to objects that can be added or
990 removed from the configuration.
991
992 Englewood will report a parameter value as None if it does not exist
993 in the data model, rather than replying with a Fault message like most
994 eNB devices.
995 """
996
997 def __init__(
998 self,
999 acs: EnodebAcsStateMachine,
1000 when_delete: str,
1001 when_add: str,
1002 when_set: str,
1003 when_skip: str,
1004 ):
1005 super().__init__()
1006 self.acs = acs
1007 self.rm_obj_transition = when_delete
1008 self.add_obj_transition = when_add
1009 self.set_params_transition = when_set
1010 self.skip_transition = when_skip
1011
1012 def get_params_to_get(self, data_model: DataModel,) -> List[ParameterName]:
1013 names = []
1014
1015 # First get base params
1016 names = get_params_to_get(
1017 self.acs.device_cfg, self.acs.data_model, request_all_params=True,
1018 )
1019 # Add object params.
1020 num_plmns = data_model.get_num_plmns()
1021 obj_to_params = data_model.get_numbered_param_names()
1022 for i in range(1, num_plmns + 1):
1023 obj_name = ParameterName.PLMN_N % i
1024 desired = obj_to_params[obj_name]
1025 names += desired
Wei-Yu Chen678f0a52021-12-21 13:50:52 +08001026
1027 print(obj_to_params)
Wei-Yu Chen49950b92021-11-08 19:19:18 +08001028 return names
1029
1030 def get_msg(self, message: Any) -> AcsMsgAndTransition:
1031 """ Respond with GetParameterValuesRequest """
1032 names = self.get_params_to_get(self.acs.data_model,)
1033
1034 # Generate the request
1035 request = models.GetParameterValues()
1036 request.ParameterNames = models.ParameterNames()
1037 request.ParameterNames.arrayType = "xsd:string[%d]" % len(names)
1038 request.ParameterNames.string = []
1039 for name in names:
1040 path = self.acs.data_model.get_parameter(name).path
1041 if path is not InvalidTrParamPath:
1042 # Only get data elements backed by tr69 path
1043 request.ParameterNames.string.append(path)
1044
1045 return AcsMsgAndTransition(msg=request, next_state=None)
1046
1047 def read_msg(self, message: Any) -> AcsReadMsgResult:
1048 """
1049 Process GetParameterValuesResponse
1050 """
1051 if not isinstance(message, models.GetParameterValuesResponse):
1052 return AcsReadMsgResult(msg_handled=False, next_state=None)
1053
1054 path_to_val = {}
1055 for param_value_struct in message.ParameterList.ParameterValueStruct:
1056 path_to_val[param_value_struct.Name] = param_value_struct.Value.Data
1057
1058 EnodebdLogger.debug("Received object parameters: %s", str(path_to_val))
1059
1060 # Parse simple params
1061 param_name_list = self.acs.data_model.get_parameter_names()
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +08001062
Wei-Yu Chen49950b92021-11-08 19:19:18 +08001063 for name in param_name_list:
1064 path = self.acs.data_model.get_parameter(name).path
1065 if path in path_to_val:
1066 value = path_to_val.get(path)
1067 magma_val = self.acs.data_model.transform_for_magma(name, value,)
1068 self.acs.device_cfg.set_parameter(name, magma_val)
1069
1070 # Parse object params
1071 num_plmns = self.acs.data_model.get_num_plmns()
1072 for i in range(1, num_plmns + 1):
1073 obj_name = ParameterName.PLMN_N % i
1074 obj_to_params = self.acs.data_model.get_numbered_param_names()
1075 param_name_list = obj_to_params[obj_name]
1076 for name in param_name_list:
1077 path = self.acs.data_model.get_parameter(name).path
1078 if path in path_to_val:
1079 value = path_to_val.get(path)
1080 if value is None:
1081 continue
1082 if obj_name not in self.acs.device_cfg.get_object_names():
1083 self.acs.device_cfg.add_object(obj_name)
1084 magma_value = self.acs.data_model.transform_for_magma(name, value)
1085 self.acs.device_cfg.set_parameter_for_object(
1086 name, magma_value, obj_name,
1087 )
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +08001088
Wei-Yu Chen49950b92021-11-08 19:19:18 +08001089 # Now we have enough information to build the desired configuration
1090 if self.acs.desired_cfg is None:
1091 self.acs.desired_cfg = build_desired_config(
1092 self.acs.mconfig,
1093 self.acs.service_config,
1094 self.acs.device_cfg,
1095 self.acs.data_model,
1096 self.acs.config_postprocessor,
1097 )
1098
1099 if (
1100 len(get_all_objects_to_delete(self.acs.desired_cfg, self.acs.device_cfg,),)
1101 > 0
1102 ):
1103 return AcsReadMsgResult(
1104 msg_handled=True, next_state=self.rm_obj_transition,
1105 )
1106 elif (
1107 len(get_all_objects_to_add(self.acs.desired_cfg, self.acs.device_cfg,),) > 0
1108 ):
1109 return AcsReadMsgResult(
1110 msg_handled=True, next_state=self.add_obj_transition,
1111 )
1112 elif (
1113 len(
1114 get_all_param_values_to_set(
1115 self.acs.desired_cfg, self.acs.device_cfg, self.acs.data_model,
1116 ),
1117 )
1118 > 0
1119 ):
1120 return AcsReadMsgResult(
1121 msg_handled=True, next_state=self.set_params_transition,
1122 )
1123 return AcsReadMsgResult(msg_handled=True, next_state=self.skip_transition,)
1124
1125 def state_description(self) -> str:
1126 return "Getting well known parameters"