blob: 9ad6b00fbdf609bbb6275e0f57192691fc19d2b5 [file] [log] [blame]
Wei-Yu Chenad55cb82022-02-15 20:07:01 +08001# SPDX-FileCopyrightText: 2020 The Magma Authors.
2# SPDX-FileCopyrightText: 2022 Open Networking Foundation <support@opennetworking.org>
3#
4# SPDX-License-Identifier: BSD-3-Clause
Wei-Yu Chen49950b92021-11-08 19:19:18 +08005
Wei-Yu Chen49950b92021-11-08 19:19:18 +08006import logging
7from typing import Any, Callable, Dict, List, Optional, Type
8
9from common.service import MagmaService
10from data_models import transform_for_magma
11from data_models.data_model import (
12 DataModel,
13 InvalidTrParamPath,
14 TrParam,
15)
16from data_models.data_model_parameters import (
17 ParameterName,
18 TrParameterType,
19)
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +080020from configuration.service_configs import load_enb_config
Wei-Yu Chen49950b92021-11-08 19:19:18 +080021from device_config.configuration_init import build_desired_config
22from device_config.enodeb_config_postprocessor import EnodebConfigurationPostProcessor
23from device_config.enodeb_configuration import EnodebConfiguration
24from devices.device_utils import EnodebDeviceName
25from logger import EnodebdLogger
26from state_machines.acs_state_utils import (
27 get_all_objects_to_add,
28 get_all_objects_to_delete,
29 get_all_param_values_to_set,
30 get_params_to_get,
31 parse_get_parameter_values_response,
32)
33from state_machines.enb_acs import EnodebAcsStateMachine
34from state_machines.enb_acs_impl import BasicEnodebAcsStateMachine
35from state_machines.enb_acs_states import (
36 AcsMsgAndTransition,
37 AcsReadMsgResult,
38 AddObjectsState,
39 DeleteObjectsState,
40 EnbSendRebootState,
41 EndSessionState,
42 EnodebAcsState,
43 ErrorState,
Wei-Yu Chen678f0a52021-12-21 13:50:52 +080044 DownloadState,
45 WaitDownloadResponseState,
46 WaitInformTransferCompleteState,
Wei-Yu Chen49950b92021-11-08 19:19:18 +080047 GetParametersState,
48 SetParameterValuesState,
49 WaitGetParametersState,
50 WaitInformMRebootState,
51 WaitInformState,
52 WaitRebootResponseState,
53 WaitSetParameterValuesState,
54)
55from tr069 import models
56
57
Wei-Yu Chen678f0a52021-12-21 13:50:52 +080058FAPSERVICE_PATH = "Device.Services.FAPService.1."
59FAP_CONTROL = FAPSERVICE_PATH + "FAPControl."
60
61
62class FreedomFiOneHandler(BasicEnodebAcsStateMachine):
63 def __init__(self, service: MagmaService,) -> None:
64 self._state_map = {}
65 super().__init__(service=service, use_param_key=True)
66
67 def reboot_asap(self) -> None:
68 self.transition("reboot")
69
70 def is_enodeb_connected(self) -> bool:
71 return not isinstance(self.state, WaitInformState)
72
73 def _init_state_map(self) -> None:
74 self._state_map = {
75 # Inform comes in -> Respond with InformResponse
76 "wait_inform": WaitInformState(self, when_done="get_rpc_methods"),
77 # If first inform after boot -> GetRpc request comes in, if not
78 # empty request comes in => Transition to get_transient_params
79 "get_rpc_methods": FreedomFiOneGetInitState(
80 self, when_done="get_transient_params",
81 ),
82 # Read transient readonly params.
83 "get_transient_params": FreedomFiOneSendGetTransientParametersState(
84 self, when_upgrade="firmware_upgrade", when_done="get_params",
85 ),
86 "firmware_upgrade": DownloadState(self, when_done="wait_download_response"),
87 "wait_download_response": WaitDownloadResponseState(
88 self, when_done="wait_transfer_complete"
89 ),
90 "wait_transfer_complete": WaitInformTransferCompleteState(
91 self,
92 when_done="get_params",
93 when_periodic="wait_transfer_complete",
94 when_timeout="end_session",
95 ),
96 "get_params": FreedomFiOneGetObjectParametersState(
97 self,
98 when_delete="delete_objs",
99 when_add="add_objs",
100 when_set="set_params",
101 when_skip="end_session",
102 ),
103 "delete_objs": DeleteObjectsState(
104 self, when_add="add_objs", when_skip="set_params",
105 ),
106 "add_objs": AddObjectsState(self, when_done="set_params"),
107 "set_params": SetParameterValuesState(self, when_done="wait_set_params",),
108 "wait_set_params": WaitSetParameterValuesState(
109 self,
110 when_done="check_get_params",
111 when_apply_invasive="check_get_params",
112 status_non_zero_allowed=True,
113 ),
114 "check_get_params": GetParametersState(
115 self, when_done="check_wait_get_params", request_all_params=True,
116 ),
117 "check_wait_get_params": WaitGetParametersState(
118 self, when_done="end_session",
119 ),
120 "end_session": EndSessionState(self),
121 # These states are only entered through manual user intervention
122 "reboot": EnbSendRebootState(self, when_done="wait_reboot"),
123 "wait_reboot": WaitRebootResponseState(
124 self, when_done="wait_post_reboot_inform",
125 ),
126 "wait_post_reboot_inform": WaitInformMRebootState(
127 self, when_done="wait_empty", when_timeout="wait_inform",
128 ),
129 # The states below are entered when an unexpected message type is
130 # received
131 "unexpected_fault": ErrorState(
132 self, inform_transition_target="wait_inform",
133 ),
134 }
135
136 @property
137 def device_name(self) -> str:
138 return EnodebDeviceName.FREEDOMFI_ONE
139
140 @property
141 def data_model_class(self) -> Type[DataModel]:
142 return FreedomFiOneTrDataModel
143
144 @property
145 def config_postprocessor(self) -> EnodebConfigurationPostProcessor:
146 return FreedomFiOneConfigurationInitializer(self)
147
148 @property
149 def state_map(self) -> Dict[str, EnodebAcsState]:
150 return self._state_map
151
152 @property
153 def disconnected_state_name(self) -> str:
154 return "wait_inform"
155
156 @property
157 def unexpected_fault_state_name(self) -> str:
158 return "unexpected_fault"
159
160
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800161class SASParameters:
162 """ Class modeling the SAS parameters and their TR path"""
163
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800164 # For CBRS radios we set this to the limit and the SAS can reduce the
165 # power if needed.
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800166
167 SAS_PARAMETERS = {
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800168 ParameterName.SAS_ENABLE: TrParam(
169 FAP_CONTROL + "LTE.X_SCM_SAS.Enable",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800170 is_invasive=False,
171 type=TrParameterType.BOOLEAN,
172 is_optional=False,
173 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800174 ParameterName.SAS_SERVER_URL: TrParam(
175 FAP_CONTROL + "LTE.X_SCM_SAS.Server",
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_UID: TrParam(
181 FAP_CONTROL + "LTE.X_SCM_SAS.UserContactInformation",
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_CATEGORY: TrParam(
187 FAP_CONTROL + "LTE.X_SCM_SAS.Category",
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_CHANNEL_TYPE: TrParam(
193 FAP_CONTROL + "LTE.X_SCM_SAS.ProtectionLevel",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800194 is_invasive=False,
195 type=TrParameterType.STRING,
196 is_optional=False,
197 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800198 ParameterName.SAS_CERT_SUBJECT: TrParam(
199 FAP_CONTROL + "LTE.X_SCM_SAS.CertSubject",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800200 is_invasive=False,
201 type=TrParameterType.STRING,
202 is_optional=False,
203 ),
204 # SAS_IC_GROUP_ID: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800205 # FAP_CONTROL + 'LTE.X_SCM_SAS.ICGGroupId', is_invasive=False,
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800206 # type=TrParameterType.STRING, False),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800207 ParameterName.SAS_LOCATION: TrParam(
208 FAP_CONTROL + "LTE.X_SCM_SAS.Location",
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_HEIGHT_TYPE: TrParam(
214 FAP_CONTROL + "LTE.X_SCM_SAS.HeightType",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800215 is_invasive=False,
216 type=TrParameterType.STRING,
217 is_optional=False,
218 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800219 ParameterName.SAS_CPI_ENABLE: TrParam(
220 FAP_CONTROL + "LTE.X_SCM_SAS.CPIEnable",
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_CPI_IPE: TrParam(
226 FAP_CONTROL + "LTE.X_SCM_SAS.CPIInstallParamSuppliedEnable",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800227 is_invasive=False,
228 type=TrParameterType.BOOLEAN,
229 is_optional=False,
230 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800231 ParameterName.SAS_FCCID: TrParam(
232 FAP_CONTROL + "LTE.X_SCM_SAS.FCCIdentificationNumber",
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_MEAS_CAPS: TrParam(
238 FAP_CONTROL + "LTE.X_SCM_SAS.MeasCapability",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800239 is_invasive=False,
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800240 type=TrParameterType.STRING,
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800241 is_optional=False,
242 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800243 ParameterName.SAS_MANU_ENABLE: TrParam(
244 FAP_CONTROL + "LTE.X_SCM_SAS.ManufacturerPrefixEnable",
245 is_invasive=False,
246 type=TrParameterType.BOOLEAN,
247 is_optional=False,
248 ),
249 ParameterName.SAS_CPI_NAME: TrParam(
250 FAP_CONTROL + "LTE.X_SCM_SAS.CPIName",
251 is_invasive=False,
252 type=TrParameterType.STRING,
253 is_optional=False,
254 ),
255 ParameterName.SAS_CPI_ID: TrParam(
256 FAP_CONTROL + "LTE.X_SCM_SAS.CPIId",
257 is_invasive=False,
258 type=TrParameterType.STRING,
259 is_optional=False,
260 ),
261 ParameterName.SAS_ANTA_AZIMUTH: TrParam(
262 FAP_CONTROL + "LTE.X_SCM_SAS.AntennaAzimuth",
263 is_invasive=False,
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800264 type=TrParameterType.INT,
265 is_optional=False,
266 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800267 ParameterName.SAS_ANTA_DOWNTILT: TrParam(
268 FAP_CONTROL + "LTE.X_SCM_SAS.AntennaDowntilt",
269 is_invasive=False,
270 type=TrParameterType.INT,
271 is_optional=False,
272 ),
273 ParameterName.SAS_ANTA_GAIN: TrParam(
274 FAP_CONTROL + "LTE.X_SCM_SAS.AntennaGain",
275 is_invasive=False,
276 type=TrParameterType.INT,
277 is_optional=False,
278 ),
279 ParameterName.SAS_ANTA_BEAMWIDTH: TrParam(
280 FAP_CONTROL + "LTE.X_SCM_SAS.AntennaBeamwidth",
281 is_invasive=False,
282 type=TrParameterType.INT,
283 is_optional=False,
284 ),
285 ParameterName.SAS_CPI_DATA: TrParam(
286 FAP_CONTROL + "LTE.X_SCM_SAS.CPISignatureData",
287 is_invasive=False,
288 type=TrParameterType.STRING,
289 is_optional=False,
290 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800291 }
292
293
294class StatusParameters:
295 """
296 Stateful class that converts eNB status to Magma understood status.
297 FreedomFiOne has many status params that interact with each other.
298 This class maintains the business logic of parsing these status params
299 and converting it to Magma understood fields.
300 """
301
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800302 # Status parameters
303 DEFAULT_GW = "defaultGW"
304 SYNC_STATUS = "syncStatus"
305 SAS_STATUS = "sasStatus"
306 ENB_STATUS = "enbStatus"
307 GPS_SCAN_STATUS = "gpsScanStatus"
308
309 STATUS_PARAMETERS = {
310 # Status nodes
311 DEFAULT_GW: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800312 "Device.X_SCM_DeviceFeature.X_SCM_NEStatus.X_SCM_DEFGW_Status",
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 SAS_STATUS: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800318 "Device.Services.FAPService.1.FAPControl.LTE.X_SCM_SAS.State",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800319 is_invasive=False,
320 type=TrParameterType.STRING,
321 is_optional=False,
322 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800323 GPS_SCAN_STATUS: TrParam(
324 "Device.FAP.GPS.ScanStatus",
325 is_invasive=False,
326 type=TrParameterType.STRING,
327 is_optional=False,
328 ),
329 ParameterName.GPS_LAT: TrParam(
330 "Device.FAP.GPS.LockedLatitude",
331 is_invasive=False,
332 type=TrParameterType.STRING,
333 is_optional=False,
334 ),
335 ParameterName.GPS_LONG: TrParam(
336 "Device.FAP.GPS.LockedLongitude",
337 is_invasive=False,
338 type=TrParameterType.STRING,
339 is_optional=False,
340 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800341 ParameterName.SW_VERSION: TrParam(
342 "Device.DeviceInfo.SoftwareVersion",
343 is_invasive=False,
344 type=TrParameterType.STRING,
345 is_optional=False,
346 ),
347 ParameterName.SERIAL_NUMBER: TrParam(
348 "Device.DeviceInfo.SerialNumber",
349 is_invasive=False,
350 type=TrParameterType.STRING,
351 is_optional=False,
352 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800353 }
354
355 # Derived status params that don't have tr69 representation.
356 DERIVED_STATUS_PARAMETERS = {
357 ParameterName.RF_TX_STATUS: TrParam(
358 InvalidTrParamPath,
359 is_invasive=False,
360 type=TrParameterType.BOOLEAN,
361 is_optional=False,
362 ),
363 ParameterName.GPS_STATUS: TrParam(
364 InvalidTrParamPath,
365 is_invasive=False,
366 type=TrParameterType.BOOLEAN,
367 is_optional=False,
368 ),
369 ParameterName.PTP_STATUS: TrParam(
370 InvalidTrParamPath,
371 is_invasive=False,
372 type=TrParameterType.BOOLEAN,
373 is_optional=False,
374 ),
375 ParameterName.MME_STATUS: TrParam(
376 InvalidTrParamPath,
377 is_invasive=False,
378 type=TrParameterType.BOOLEAN,
379 is_optional=False,
380 ),
381 ParameterName.OP_STATE: TrParam(
382 InvalidTrParamPath,
383 is_invasive=False,
384 type=TrParameterType.BOOLEAN,
385 is_optional=False,
386 ),
387 }
388
389 @classmethod
390 def set_magma_device_cfg(
391 cls, name_to_val: Dict, device_cfg: EnodebConfiguration,
392 ):
393 """
394 Convert FreedomFiOne name_to_val representation to magma device_cfg
395 """
396 success_str = "SUCCESS" # String constant returned by radio
397 insync_str = "INSYNC"
398
399 if (
400 name_to_val.get(cls.DEFAULT_GW)
401 and name_to_val[cls.DEFAULT_GW].upper() != success_str
402 ):
403 # Nothing will proceed if the eNB doesn't have an IP on the WAN
404 serial_num = "unknown"
405 if device_cfg.has_parameter(ParameterName.SERIAL_NUMBER):
406 serial_num = device_cfg.get_parameter(ParameterName.SERIAL_NUMBER,)
407 EnodebdLogger.error(
408 "Radio with serial number %s doesn't have IP address " "on WAN",
409 serial_num,
410 )
411 device_cfg.set_parameter(
412 param_name=ParameterName.RF_TX_STATUS, value=False,
413 )
414 device_cfg.set_parameter(
415 param_name=ParameterName.GPS_STATUS, value=False,
416 )
417 device_cfg.set_parameter(
418 param_name=ParameterName.PTP_STATUS, value=False,
419 )
420 device_cfg.set_parameter(
421 param_name=ParameterName.MME_STATUS, value=False,
422 )
423 device_cfg.set_parameter(
424 param_name=ParameterName.OP_STATE, value=False,
425 )
426 return
427
428 if (
429 name_to_val.get(cls.SAS_STATUS)
430 and name_to_val[cls.SAS_STATUS].upper() == success_str
431 ):
432 device_cfg.set_parameter(
433 param_name=ParameterName.RF_TX_STATUS, value=True,
434 )
435 else:
436 # No sas grant so not transmitting. There is no explicit node for Tx
437 # in FreedomFiOne
438 device_cfg.set_parameter(
439 param_name=ParameterName.RF_TX_STATUS, value=False,
440 )
441
442 if (
443 name_to_val.get(cls.GPS_SCAN_STATUS)
444 and name_to_val[cls.GPS_SCAN_STATUS].upper() == success_str
445 ):
446 device_cfg.set_parameter(
447 param_name=ParameterName.GPS_STATUS, value=True,
448 )
449 # Time comes through GPS so can only be insync with GPS is
450 # in sync, we use PTP_STATUS field to overload timer is in Sync.
451 if (
452 name_to_val.get(cls.SYNC_STATUS)
453 and name_to_val[cls.SYNC_STATUS].upper() == insync_str
454 ):
455 device_cfg.set_parameter(
456 param_name=ParameterName.PTP_STATUS, value=True,
457 )
458 else:
459 device_cfg.set_parameter(
460 param_name=ParameterName.PTP_STATUS, value=False,
461 )
462 else:
463 device_cfg.set_parameter(
464 param_name=ParameterName.GPS_STATUS, value=False,
465 )
466 device_cfg.set_parameter(
467 param_name=ParameterName.PTP_STATUS, value=False,
468 )
469
470 if (
471 name_to_val.get(cls.DEFAULT_GW)
472 and name_to_val[cls.DEFAULT_GW].upper() == success_str
473 ):
474 device_cfg.set_parameter(
475 param_name=ParameterName.MME_STATUS, value=True,
476 )
477 else:
478 device_cfg.set_parameter(
479 param_name=ParameterName.MME_STATUS, value=False,
480 )
481
482 if (
483 name_to_val.get(cls.ENB_STATUS)
484 and name_to_val[cls.ENB_STATUS].upper() == success_str
485 ):
486 device_cfg.set_parameter(
487 param_name=ParameterName.OP_STATE, value=True,
488 )
489 else:
490 device_cfg.set_parameter(
491 param_name=ParameterName.OP_STATE, value=False,
492 )
493
494 pass_through_params = [ParameterName.GPS_LAT, ParameterName.GPS_LONG]
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800495
496 print(name_to_val)
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800497 for name in pass_through_params:
498 device_cfg.set_parameter(name, name_to_val[name])
499
500
501class FreedomFiOneMiscParameters:
502 """
503 Default set of parameters that enable carrier aggregation and other
504 miscellaneous properties
505 """
506
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800507 MISC_PARAMETERS = {
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800508 ParameterName.CARRIER_AGG_ENABLE: TrParam(
509 FAP_CONTROL + "LTE.X_SCM_RRMConfig.X_SCM_CA_Enable",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800510 is_invasive=False,
511 type=TrParameterType.BOOLEAN,
512 is_optional=False,
513 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800514 ParameterName.CARRIER_NUMBER: TrParam(
515 FAP_CONTROL + "LTE.X_SCM_RRMConfig.X_SCM_Cell_Number",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800516 is_invasive=False,
517 type=TrParameterType.INT,
518 is_optional=False,
519 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800520 ParameterName.CONTIGUOUS_CC: TrParam(
521 FAP_CONTROL + "LTE.X_SCM_RRMConfig.X_SCM_CELL_Freq_Contiguous",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800522 is_invasive=False,
523 type=TrParameterType.INT,
524 is_optional=False,
525 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800526 ParameterName.PRIM_SOURCE: TrParam(
527 FAPSERVICE_PATH + "REM.X_SCM_tfcsManagerConfig.primSrc",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800528 is_invasive=False,
529 type=TrParameterType.STRING,
530 is_optional=False,
531 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800532 ParameterName.ENABLE_CWMP: TrParam(
533 "Device.ManagementServer.EnableCWMP",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800534 is_invasive=False,
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800535 type=TrParameterType.BOOLEAN,
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800536 is_optional=False,
537 ),
538 }
539
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800540
541class FreedomFiOneTrDataModel(DataModel):
542 """
543 Class to represent relevant data model parameters from TR-196/TR-098.
544 This class is effectively read-only.
545
546 These models have these idiosyncrasies (on account of running TR098):
547
548 - Parameter content root is different (InternetGatewayDevice)
549 - GetParameter queries with a wildcard e.g. InternetGatewayDevice. do
550 not respond with the full tree (we have to query all parameters)
551 - MME status is not exposed - we assume the MME is connected if
552 the eNodeB is transmitting (OpState=true)
553 - Parameters such as band capability/duplex config
554 are rooted under `boardconf.` and not the device config root
555 - Num PLMNs is not reported by these units
556 """
557
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800558 PARAMETERS = {
559 # Top-level objects
560 ParameterName.DEVICE: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800561 "Device.",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800562 is_invasive=False,
563 type=TrParameterType.OBJECT,
564 is_optional=False,
565 ),
566 ParameterName.FAP_SERVICE: TrParam(
567 FAP_CONTROL,
568 is_invasive=False,
569 type=TrParameterType.OBJECT,
570 is_optional=False,
571 ),
572 # Device info
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800573 ParameterName.IP_ADDRESS: TrParam(
574 "Device.IP.Interface.1.IPv4Address.1.IPAddress",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800575 is_invasive=False,
576 type=TrParameterType.STRING,
577 is_optional=False,
578 ),
579 # RF-related parameters
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800580 ParameterName.FREQ_BAND_1: TrParam(
581 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.FreqBandIndicator",
582 is_invasive=False,
583 type=TrParameterType.UNSIGNED_INT,
584 is_optional=False,
585 ),
586 ParameterName.FREQ_BAND_2: TrParam(
587 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_FreqBandIndicator2",
588 is_invasive=False,
589 type=TrParameterType.UNSIGNED_INT,
590 is_optional=False,
591 ),
592 ParameterName.FREQ_BAND_LIST: TrParam(
593 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_FreqBandIndicatorConfigList",
594 is_invasive=False,
595 type=TrParameterType.STRING,
596 is_optional=False,
597 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800598 ParameterName.EARFCNDL: TrParam(
599 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.EARFCNDL",
600 is_invasive=False,
601 type=TrParameterType.INT,
602 is_optional=False,
603 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800604 ParameterName.EARFCNUL: TrParam(
605 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.EARFCNUL",
606 is_invasive=False,
607 type=TrParameterType.INT,
608 is_optional=False,
609 ),
610 ParameterName.EARFCNDL2: TrParam(
611 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_EARFCNDL2",
612 is_invasive=False,
613 type=TrParameterType.INT,
614 is_optional=False,
615 ),
616 ParameterName.EARFCNUL2: TrParam(
617 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_EARFCNUL2",
618 is_invasive=False,
619 type=TrParameterType.INT,
620 is_optional=False,
621 ),
622 ParameterName.EARFCNDL_LIST: TrParam(
623 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_EARFCNDLConfigList",
624 is_invasive=False,
625 type=TrParameterType.STRING,
626 is_optional=False,
627 ),
628 ParameterName.EARFCNUL_LIST: TrParam(
629 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_EARFCNULConfigList",
630 is_invasive=False,
631 type=TrParameterType.STRING,
632 is_optional=False,
633 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800634 ParameterName.DL_BANDWIDTH: TrParam(
635 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.DLBandwidth",
636 is_invasive=False,
637 type=TrParameterType.STRING,
638 is_optional=False,
639 ),
640 ParameterName.UL_BANDWIDTH: TrParam(
641 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.ULBandwidth",
642 is_invasive=False,
643 type=TrParameterType.STRING,
644 is_optional=False,
645 ),
646 ParameterName.PCI: TrParam(
647 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.PhyCellID",
648 is_invasive=False,
649 type=TrParameterType.STRING,
650 is_optional=False,
651 ),
652 ParameterName.SUBFRAME_ASSIGNMENT: TrParam(
653 FAPSERVICE_PATH + "CellConfig.LTE.RAN.PHY.TDDFrame.SubFrameAssignment",
654 is_invasive=False,
Wei-Yu Chenad55cb82022-02-15 20:07:01 +0800655 type=TrParameterType.INT,
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800656 is_optional=False,
657 ),
658 ParameterName.SPECIAL_SUBFRAME_PATTERN: TrParam(
659 FAPSERVICE_PATH + "CellConfig.LTE.RAN.PHY.TDDFrame.SpecialSubframePatterns",
660 is_invasive=False,
661 type=TrParameterType.INT,
662 is_optional=False,
663 ),
Wei-Yu Chenad55cb82022-02-15 20:07:01 +0800664 ParameterName.CELL_ENABLE64QAM: TrParam(
665 FAPSERVICE_PATH + "CellConfig.LTE.RAN.PHY.PUSCH.Enable64QAM",
666 is_invasive=False,
667 type=TrParameterType.BOOLEAN,
668 is_optional=False,
669 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800670 ParameterName.CELL_ID: TrParam(
671 FAPSERVICE_PATH + "CellConfig.LTE.RAN.Common.CellIdentity",
672 is_invasive=False,
673 type=TrParameterType.UNSIGNED_INT,
674 is_optional=False,
675 ),
676 # Readonly LTE state
677 ParameterName.ADMIN_STATE: TrParam(
678 FAP_CONTROL + "LTE.AdminState",
679 is_invasive=False,
680 type=TrParameterType.BOOLEAN,
681 is_optional=False,
682 ),
683 ParameterName.GPS_ENABLE: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800684 "Device.FAP.GPS.ScanOnBoot",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800685 is_invasive=False,
686 type=TrParameterType.BOOLEAN,
687 is_optional=False,
688 ),
689 # Core network parameters
690 ParameterName.MME_IP: TrParam(
691 FAP_CONTROL + "LTE.Gateway.S1SigLinkServerList",
692 is_invasive=False,
693 type=TrParameterType.STRING,
694 is_optional=False,
695 ),
696 ParameterName.MME_PORT: TrParam(
697 FAP_CONTROL + "LTE.Gateway.S1SigLinkPort",
698 is_invasive=False,
699 type=TrParameterType.INT,
700 is_optional=False,
701 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800702 ParameterName.TAC: TrParam(
703 FAPSERVICE_PATH + "CellConfig.LTE.EPC.TAC",
704 is_invasive=False,
705 type=TrParameterType.INT,
706 is_optional=False,
707 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800708 ParameterName.TAC2: TrParam(
709 FAPSERVICE_PATH + "CellConfig.LTE.EPC.X_SCM_TAC2",
710 is_invasive=False,
711 type=TrParameterType.INT,
712 is_optional=False,
713 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800714 # Management server parameters
715 ParameterName.PERIODIC_INFORM_ENABLE: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800716 "Device.ManagementServer.PeriodicInformEnable",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800717 is_invasive=False,
718 type=TrParameterType.BOOLEAN,
719 is_optional=False,
720 ),
721 ParameterName.PERIODIC_INFORM_INTERVAL: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800722 "Device.ManagementServer.PeriodicInformInterval",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800723 is_invasive=False,
724 type=TrParameterType.INT,
725 is_optional=False,
726 ),
727 # Performance management parameters
728 ParameterName.PERF_MGMT_ENABLE: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800729 "Device.FAP.PerfMgmt.Config.1.Enable",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800730 is_invasive=False,
731 type=TrParameterType.BOOLEAN,
732 is_optional=False,
733 ),
734 ParameterName.PERF_MGMT_UPLOAD_INTERVAL: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800735 "Device.FAP.PerfMgmt.Config.1.PeriodicUploadInterval",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800736 is_invasive=False,
737 type=TrParameterType.INT,
738 is_optional=False,
739 ),
740 ParameterName.PERF_MGMT_UPLOAD_URL: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800741 "Device.FAP.PerfMgmt.Config.1.URL",
742 is_invasive=False,
743 type=TrParameterType.STRING,
744 is_optional=False,
745 ),
746 ParameterName.TX_POWER: TrParam(
747 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_TxPowerConfig",
748 is_invasive=True,
749 type=TrParameterType.INT,
750 is_optional=False,
751 ),
752 ParameterName.TUNNEL_TYPE: TrParam(
753 FAPSERVICE_PATH + "CellConfig.LTE.Tunnel.1.TunnelRef",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800754 is_invasive=False,
755 type=TrParameterType.STRING,
756 is_optional=False,
757 ),
758 }
759 TRANSFORMS_FOR_ENB = {}
760 NUM_PLMNS_IN_CONFIG = 1
761 for i in range(1, NUM_PLMNS_IN_CONFIG + 1):
762 PARAMETERS[ParameterName.PLMN_N % i] = TrParam(
763 FAPSERVICE_PATH + "CellConfig.LTE.EPC.PLMNList.%d." % i,
764 is_invasive=False,
765 type=TrParameterType.STRING,
766 is_optional=False,
767 )
768 PARAMETERS[ParameterName.PLMN_N_CELL_RESERVED % i] = TrParam(
769 FAPSERVICE_PATH
770 + "CellConfig.LTE.EPC.PLMNList.%d.CellReservedForOperatorUse" % i,
771 is_invasive=False,
772 type=TrParameterType.BOOLEAN,
773 is_optional=False,
774 )
775 PARAMETERS[ParameterName.PLMN_N_ENABLE % i] = TrParam(
776 FAPSERVICE_PATH + "CellConfig.LTE.EPC.PLMNList.%d.Enable" % i,
777 is_invasive=False,
778 type=TrParameterType.BOOLEAN,
779 is_optional=False,
780 )
781 PARAMETERS[ParameterName.PLMN_N_PRIMARY % i] = TrParam(
782 FAPSERVICE_PATH + "CellConfig.LTE.EPC.PLMNList.%d.IsPrimary" % i,
783 is_invasive=False,
784 type=TrParameterType.BOOLEAN,
785 is_optional=False,
786 )
787 PARAMETERS[ParameterName.PLMN_N_PLMNID % i] = TrParam(
788 FAPSERVICE_PATH + "CellConfig.LTE.EPC.PLMNList.%d.PLMNID" % i,
789 is_invasive=False,
790 type=TrParameterType.STRING,
791 is_optional=False,
792 )
793
794 PARAMETERS.update(SASParameters.SAS_PARAMETERS)
795 PARAMETERS.update(FreedomFiOneMiscParameters.MISC_PARAMETERS)
796 PARAMETERS.update(StatusParameters.STATUS_PARAMETERS)
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800797 PARAMETERS.update(StatusParameters.DERIVED_STATUS_PARAMETERS)
798
799 TRANSFORMS_FOR_MAGMA = {
800 # We don't set these parameters
801 ParameterName.BAND_CAPABILITY: transform_for_magma.band_capability,
802 ParameterName.DUPLEX_MODE_CAPABILITY: transform_for_magma.duplex_mode,
803 }
804
805 @classmethod
806 def get_parameter(cls, param_name: ParameterName) -> Optional[TrParam]:
807 return cls.PARAMETERS.get(param_name)
808
809 @classmethod
810 def _get_magma_transforms(cls,) -> Dict[ParameterName, Callable[[Any], Any]]:
811 return cls.TRANSFORMS_FOR_MAGMA
812
813 @classmethod
814 def _get_enb_transforms(cls) -> Dict[ParameterName, Callable[[Any], Any]]:
815 return cls.TRANSFORMS_FOR_ENB
816
817 @classmethod
818 def get_load_parameters(cls) -> List[ParameterName]:
819 """
820 Load all the parameters instead of a subset.
821 """
822 return list(cls.PARAMETERS.keys())
823
824 @classmethod
825 def get_num_plmns(cls) -> int:
826 return cls.NUM_PLMNS_IN_CONFIG
827
828 @classmethod
829 def get_parameter_names(cls) -> List[ParameterName]:
830 excluded_params = [
831 str(ParameterName.DEVICE),
832 str(ParameterName.FAP_SERVICE),
833 ]
834 names = list(
835 filter(
836 lambda x: (not str(x).startswith("PLMN"))
837 and (str(x) not in excluded_params),
838 cls.PARAMETERS.keys(),
839 ),
840 )
841 return names
842
843 @classmethod
844 def get_numbered_param_names(cls,) -> Dict[ParameterName, List[ParameterName]]:
845 names = {}
846 for i in range(1, cls.NUM_PLMNS_IN_CONFIG + 1):
847 params = [
848 ParameterName.PLMN_N_CELL_RESERVED % i,
849 ParameterName.PLMN_N_ENABLE % i,
850 ParameterName.PLMN_N_PRIMARY % i,
851 ParameterName.PLMN_N_PLMNID % i,
852 ]
853 names[ParameterName.PLMN_N % i] = params
854
855 return names
856
857 @classmethod
858 def get_sas_param_names(cls) -> List[ParameterName]:
859 return SASParameters.SAS_PARAMETERS.keys()
860
861
862class FreedomFiOneConfigurationInitializer(EnodebConfigurationPostProcessor):
863 """
864 Class to add the sas related parameters to the desired config.
865 """
866
867 SAS_KEY = "sas"
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800868
869 def __init__(self, acs: EnodebAcsStateMachine):
870 super().__init__()
871 self.acs = acs
872
873 def postprocess(
874 self, mconfig: Any, service_cfg: Any, desired_cfg: EnodebConfiguration,
875 ) -> None:
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800876 # Bump up the parameter key version
877 self.acs.parameter_version_inc()
878
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +0800879 # Load eNB customized configuration from "./magma_config/serial_number/"
880 # and configure each connected eNB based on serial number
881 enbcfg = load_enb_config()
882 sn = self.acs.get_parameter(ParameterName.SERIAL_NUMBER)
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800883
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +0800884 for name, val in enbcfg.get(sn, {}).items():
885 # The SAS configuration for eNodeB
886 if name in ["sas", "cell"]:
887 for subname, subval in val.items():
888 print("Config %s updated to: %s" % (subname, subval))
889 desired_cfg.set_parameter(subname, subval)
890
891 print(desired_cfg)
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800892
893
894class FreedomFiOneSendGetTransientParametersState(EnodebAcsState):
895 """
896 Periodically read eNodeB status. Note: keep frequency low to avoid
897 backing up large numbers of read operations if enodebd is busy.
898 Some eNB parameters are read only and updated by the eNB itself.
899 """
900
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800901 def __init__(self, acs: EnodebAcsStateMachine, when_upgrade: str, when_done: str):
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800902 super().__init__()
903 self.acs = acs
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800904 self.upgrade_transition = when_upgrade
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800905 self.done_transition = when_done
906
907 def get_msg(self, message: Any) -> AcsMsgAndTransition:
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +0800908
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800909 request = models.GetParameterValues()
910 request.ParameterNames = models.ParameterNames()
911 request.ParameterNames.string = []
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +0800912
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800913 for _, tr_param in StatusParameters.STATUS_PARAMETERS.items():
914 path = tr_param.path
915 request.ParameterNames.string.append(path)
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +0800916
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800917 request.ParameterNames.arrayType = "xsd:string[%d]" % len(
918 request.ParameterNames.string
919 )
920
921 return AcsMsgAndTransition(msg=request, next_state=None)
922
923 def read_msg(self, message: Any) -> AcsReadMsgResult:
924
925 if not isinstance(message, models.GetParameterValuesResponse):
926 return AcsReadMsgResult(msg_handled=False, next_state=None)
927 # Current values of the fetched parameters
928 name_to_val = parse_get_parameter_values_response(self.acs.data_model, message,)
929 EnodebdLogger.debug("Received Parameters: %s", str(name_to_val))
930
931 # Update device configuration
932 StatusParameters.set_magma_device_cfg(
933 name_to_val, self.acs.device_cfg,
934 )
935
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800936 print("In get transient state", name_to_val, type(name_to_val))
937 if name_to_val["SW version"] != "TEST3918@210224":
938 print("Get into Firmware Upgrade state")
939 return AcsReadMsgResult(
940 msg_handled=True, next_state=self.upgrade_transition
941 )
942
943 print("Skip firmware upgrade, configure the enb")
944 return AcsReadMsgResult(msg_handled=True, next_state=self.done_transition)
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800945
946 def state_description(self) -> str:
947 return "Getting transient read-only parameters"
948
949
950class FreedomFiOneGetInitState(EnodebAcsState):
951 """
952 After the first Inform message the following can happen:
953 1 - eNB can try to learn the RPC method of the ACS, reply back with the
954 RPC response (happens right after boot)
955 2 - eNB can send an empty message -> This means that the eNB is already
956 provisioned so transition to next state. Only transition to next state
957 after this message.
958 3 - Some other method call that we don't care about so ignore.
959 expected that the eNB -> This is an unhandled state so unlikely
960 """
961
962 def __init__(self, acs: EnodebAcsStateMachine, when_done):
963 super().__init__()
964 self.acs = acs
965 self.done_transition = when_done
966 self._is_rpc_request = False
967
968 def get_msg(self, message: Any) -> AcsMsgAndTransition:
969 """
970 Return empty message response if care about this
971 message type otherwise return empty RPC methods response.
972 """
973 if not self._is_rpc_request:
974 resp = models.DummyInput()
975 return AcsMsgAndTransition(msg=resp, next_state=None)
976
977 resp = models.GetRPCMethodsResponse()
978 resp.MethodList = models.MethodList()
979 RPC_METHODS = ["Inform", "GetRPCMethods", "TransferComplete"]
980 resp.MethodList.arrayType = "xsd:string[%d]" % len(RPC_METHODS)
981 resp.MethodList.string = RPC_METHODS
982 # Don't transition to next state wait for the empty HTTP post
983 return AcsMsgAndTransition(msg=resp, next_state=None)
984
985 def read_msg(self, message: Any) -> AcsReadMsgResult:
986 # If this is a regular Inform, not after a reboot we'll get an empty
987 # message, in this case transition to the next state. We consider
988 # this phase as "initialized"
989 if isinstance(message, models.DummyInput):
990 return AcsReadMsgResult(msg_handled=True, next_state=self.done_transition,)
991 if not isinstance(message, models.GetRPCMethods):
992 # Unexpected, just don't die, ignore message.
993 logging.error("Ignoring message %s", str(type(message)))
994 # Set this so get_msg will return an empty message
995 self._is_rpc_request = False
996 else:
997 # Return a valid RPC response
998 self._is_rpc_request = True
999 return AcsReadMsgResult(msg_handled=True, next_state=None)
1000
1001 def state_description(self) -> str:
1002 return "Initializing the post boot sequence for eNB"
1003
1004
1005class FreedomFiOneGetObjectParametersState(EnodebAcsState):
1006 """
1007 Get information on parameters belonging to objects that can be added or
1008 removed from the configuration.
1009
1010 Englewood will report a parameter value as None if it does not exist
1011 in the data model, rather than replying with a Fault message like most
1012 eNB devices.
1013 """
1014
1015 def __init__(
1016 self,
1017 acs: EnodebAcsStateMachine,
1018 when_delete: str,
1019 when_add: str,
1020 when_set: str,
1021 when_skip: str,
1022 ):
1023 super().__init__()
1024 self.acs = acs
1025 self.rm_obj_transition = when_delete
1026 self.add_obj_transition = when_add
1027 self.set_params_transition = when_set
1028 self.skip_transition = when_skip
1029
1030 def get_params_to_get(self, data_model: DataModel,) -> List[ParameterName]:
1031 names = []
1032
1033 # First get base params
1034 names = get_params_to_get(
1035 self.acs.device_cfg, self.acs.data_model, request_all_params=True,
1036 )
1037 # Add object params.
1038 num_plmns = data_model.get_num_plmns()
1039 obj_to_params = data_model.get_numbered_param_names()
1040 for i in range(1, num_plmns + 1):
1041 obj_name = ParameterName.PLMN_N % i
1042 desired = obj_to_params[obj_name]
1043 names += desired
Wei-Yu Chen678f0a52021-12-21 13:50:52 +08001044
1045 print(obj_to_params)
Wei-Yu Chen49950b92021-11-08 19:19:18 +08001046 return names
1047
1048 def get_msg(self, message: Any) -> AcsMsgAndTransition:
1049 """ Respond with GetParameterValuesRequest """
1050 names = self.get_params_to_get(self.acs.data_model,)
1051
1052 # Generate the request
1053 request = models.GetParameterValues()
1054 request.ParameterNames = models.ParameterNames()
1055 request.ParameterNames.arrayType = "xsd:string[%d]" % len(names)
1056 request.ParameterNames.string = []
1057 for name in names:
1058 path = self.acs.data_model.get_parameter(name).path
1059 if path is not InvalidTrParamPath:
1060 # Only get data elements backed by tr69 path
1061 request.ParameterNames.string.append(path)
1062
1063 return AcsMsgAndTransition(msg=request, next_state=None)
1064
1065 def read_msg(self, message: Any) -> AcsReadMsgResult:
1066 """
1067 Process GetParameterValuesResponse
1068 """
1069 if not isinstance(message, models.GetParameterValuesResponse):
1070 return AcsReadMsgResult(msg_handled=False, next_state=None)
1071
1072 path_to_val = {}
1073 for param_value_struct in message.ParameterList.ParameterValueStruct:
1074 path_to_val[param_value_struct.Name] = param_value_struct.Value.Data
1075
1076 EnodebdLogger.debug("Received object parameters: %s", str(path_to_val))
1077
1078 # Parse simple params
1079 param_name_list = self.acs.data_model.get_parameter_names()
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +08001080
Wei-Yu Chen49950b92021-11-08 19:19:18 +08001081 for name in param_name_list:
1082 path = self.acs.data_model.get_parameter(name).path
1083 if path in path_to_val:
1084 value = path_to_val.get(path)
1085 magma_val = self.acs.data_model.transform_for_magma(name, value,)
1086 self.acs.device_cfg.set_parameter(name, magma_val)
1087
1088 # Parse object params
1089 num_plmns = self.acs.data_model.get_num_plmns()
1090 for i in range(1, num_plmns + 1):
1091 obj_name = ParameterName.PLMN_N % i
1092 obj_to_params = self.acs.data_model.get_numbered_param_names()
1093 param_name_list = obj_to_params[obj_name]
1094 for name in param_name_list:
1095 path = self.acs.data_model.get_parameter(name).path
1096 if path in path_to_val:
1097 value = path_to_val.get(path)
1098 if value is None:
1099 continue
1100 if obj_name not in self.acs.device_cfg.get_object_names():
1101 self.acs.device_cfg.add_object(obj_name)
1102 magma_value = self.acs.data_model.transform_for_magma(name, value)
1103 self.acs.device_cfg.set_parameter_for_object(
1104 name, magma_value, obj_name,
1105 )
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +08001106
Wei-Yu Chen49950b92021-11-08 19:19:18 +08001107 # Now we have enough information to build the desired configuration
1108 if self.acs.desired_cfg is None:
1109 self.acs.desired_cfg = build_desired_config(
1110 self.acs.mconfig,
1111 self.acs.service_config,
1112 self.acs.device_cfg,
1113 self.acs.data_model,
1114 self.acs.config_postprocessor,
1115 )
1116
1117 if (
1118 len(get_all_objects_to_delete(self.acs.desired_cfg, self.acs.device_cfg,),)
1119 > 0
1120 ):
1121 return AcsReadMsgResult(
1122 msg_handled=True, next_state=self.rm_obj_transition,
1123 )
1124 elif (
1125 len(get_all_objects_to_add(self.acs.desired_cfg, self.acs.device_cfg,),) > 0
1126 ):
1127 return AcsReadMsgResult(
1128 msg_handled=True, next_state=self.add_obj_transition,
1129 )
1130 elif (
1131 len(
1132 get_all_param_values_to_set(
1133 self.acs.desired_cfg, self.acs.device_cfg, self.acs.data_model,
1134 ),
1135 )
1136 > 0
1137 ):
1138 return AcsReadMsgResult(
1139 msg_handled=True, next_state=self.set_params_transition,
1140 )
1141 return AcsReadMsgResult(msg_handled=True, next_state=self.skip_transition,)
1142
1143 def state_description(self) -> str:
1144 return "Getting well known parameters"