blob: 4dfee90298c205e19324ae428bad1ec98534937c [file] [log] [blame]
Wei-Yu Chen49950b92021-11-08 19:19:18 +08001"""
2Copyright 2020 The Magma Authors.
3
4This 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"""
13import 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,
Wei-Yu Chen678f0a52021-12-21 13:50:52 +080051 DownloadState,
52 WaitDownloadResponseState,
53 WaitInformTransferCompleteState,
Wei-Yu Chen49950b92021-11-08 19:19:18 +080054 GetParametersState,
55 SetParameterValuesState,
56 WaitGetParametersState,
57 WaitInformMRebootState,
58 WaitInformState,
59 WaitRebootResponseState,
60 WaitSetParameterValuesState,
61)
62from tr069 import models
63
64
Wei-Yu Chen678f0a52021-12-21 13:50:52 +080065FAPSERVICE_PATH = "Device.Services.FAPService.1."
66FAP_CONTROL = FAPSERVICE_PATH + "FAPControl."
67
68
69class FreedomFiOneHandler(BasicEnodebAcsStateMachine):
70 def __init__(self, service: MagmaService,) -> None:
71 self._state_map = {}
72 super().__init__(service=service, use_param_key=True)
73
74 def reboot_asap(self) -> None:
75 self.transition("reboot")
76
77 def is_enodeb_connected(self) -> bool:
78 return not isinstance(self.state, WaitInformState)
79
80 def _init_state_map(self) -> None:
81 self._state_map = {
82 # Inform comes in -> Respond with InformResponse
83 "wait_inform": WaitInformState(self, when_done="get_rpc_methods"),
84 # If first inform after boot -> GetRpc request comes in, if not
85 # empty request comes in => Transition to get_transient_params
86 "get_rpc_methods": FreedomFiOneGetInitState(
87 self, when_done="get_transient_params",
88 ),
89 # Read transient readonly params.
90 "get_transient_params": FreedomFiOneSendGetTransientParametersState(
91 self, when_upgrade="firmware_upgrade", when_done="get_params",
92 ),
93 "firmware_upgrade": DownloadState(self, when_done="wait_download_response"),
94 "wait_download_response": WaitDownloadResponseState(
95 self, when_done="wait_transfer_complete"
96 ),
97 "wait_transfer_complete": WaitInformTransferCompleteState(
98 self,
99 when_done="get_params",
100 when_periodic="wait_transfer_complete",
101 when_timeout="end_session",
102 ),
103 "get_params": FreedomFiOneGetObjectParametersState(
104 self,
105 when_delete="delete_objs",
106 when_add="add_objs",
107 when_set="set_params",
108 when_skip="end_session",
109 ),
110 "delete_objs": DeleteObjectsState(
111 self, when_add="add_objs", when_skip="set_params",
112 ),
113 "add_objs": AddObjectsState(self, when_done="set_params"),
114 "set_params": SetParameterValuesState(self, when_done="wait_set_params",),
115 "wait_set_params": WaitSetParameterValuesState(
116 self,
117 when_done="check_get_params",
118 when_apply_invasive="check_get_params",
119 status_non_zero_allowed=True,
120 ),
121 "check_get_params": GetParametersState(
122 self, when_done="check_wait_get_params", request_all_params=True,
123 ),
124 "check_wait_get_params": WaitGetParametersState(
125 self, when_done="end_session",
126 ),
127 "end_session": EndSessionState(self),
128 # These states are only entered through manual user intervention
129 "reboot": EnbSendRebootState(self, when_done="wait_reboot"),
130 "wait_reboot": WaitRebootResponseState(
131 self, when_done="wait_post_reboot_inform",
132 ),
133 "wait_post_reboot_inform": WaitInformMRebootState(
134 self, when_done="wait_empty", when_timeout="wait_inform",
135 ),
136 # The states below are entered when an unexpected message type is
137 # received
138 "unexpected_fault": ErrorState(
139 self, inform_transition_target="wait_inform",
140 ),
141 }
142
143 @property
144 def device_name(self) -> str:
145 return EnodebDeviceName.FREEDOMFI_ONE
146
147 @property
148 def data_model_class(self) -> Type[DataModel]:
149 return FreedomFiOneTrDataModel
150
151 @property
152 def config_postprocessor(self) -> EnodebConfigurationPostProcessor:
153 return FreedomFiOneConfigurationInitializer(self)
154
155 @property
156 def state_map(self) -> Dict[str, EnodebAcsState]:
157 return self._state_map
158
159 @property
160 def disconnected_state_name(self) -> str:
161 return "wait_inform"
162
163 @property
164 def unexpected_fault_state_name(self) -> str:
165 return "unexpected_fault"
166
167
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800168class SASParameters:
169 """ Class modeling the SAS parameters and their TR path"""
170
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800171 # For CBRS radios we set this to the limit and the SAS can reduce the
172 # power if needed.
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800173
174 SAS_PARAMETERS = {
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800175 ParameterName.SAS_ENABLE: TrParam(
176 FAP_CONTROL + "LTE.X_SCM_SAS.Enable",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800177 is_invasive=False,
178 type=TrParameterType.BOOLEAN,
179 is_optional=False,
180 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800181 ParameterName.SAS_SERVER_URL: TrParam(
182 FAP_CONTROL + "LTE.X_SCM_SAS.Server",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800183 is_invasive=False,
184 type=TrParameterType.STRING,
185 is_optional=False,
186 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800187 ParameterName.SAS_UID: TrParam(
188 FAP_CONTROL + "LTE.X_SCM_SAS.UserContactInformation",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800189 is_invasive=False,
190 type=TrParameterType.STRING,
191 is_optional=False,
192 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800193 ParameterName.SAS_CATEGORY: TrParam(
194 FAP_CONTROL + "LTE.X_SCM_SAS.Category",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800195 is_invasive=False,
196 type=TrParameterType.STRING,
197 is_optional=False,
198 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800199 ParameterName.SAS_CHANNEL_TYPE: TrParam(
200 FAP_CONTROL + "LTE.X_SCM_SAS.ProtectionLevel",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800201 is_invasive=False,
202 type=TrParameterType.STRING,
203 is_optional=False,
204 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800205 ParameterName.SAS_CERT_SUBJECT: TrParam(
206 FAP_CONTROL + "LTE.X_SCM_SAS.CertSubject",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800207 is_invasive=False,
208 type=TrParameterType.STRING,
209 is_optional=False,
210 ),
211 # SAS_IC_GROUP_ID: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800212 # FAP_CONTROL + 'LTE.X_SCM_SAS.ICGGroupId', is_invasive=False,
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800213 # type=TrParameterType.STRING, False),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800214 ParameterName.SAS_LOCATION: TrParam(
215 FAP_CONTROL + "LTE.X_SCM_SAS.Location",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800216 is_invasive=False,
217 type=TrParameterType.STRING,
218 is_optional=False,
219 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800220 ParameterName.SAS_HEIGHT_TYPE: TrParam(
221 FAP_CONTROL + "LTE.X_SCM_SAS.HeightType",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800222 is_invasive=False,
223 type=TrParameterType.STRING,
224 is_optional=False,
225 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800226 ParameterName.SAS_CPI_ENABLE: TrParam(
227 FAP_CONTROL + "LTE.X_SCM_SAS.CPIEnable",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800228 is_invasive=False,
229 type=TrParameterType.BOOLEAN,
230 is_optional=False,
231 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800232 ParameterName.SAS_CPI_IPE: TrParam(
233 FAP_CONTROL + "LTE.X_SCM_SAS.CPIInstallParamSuppliedEnable",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800234 is_invasive=False,
235 type=TrParameterType.BOOLEAN,
236 is_optional=False,
237 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800238 ParameterName.SAS_FCCID: TrParam(
239 FAP_CONTROL + "LTE.X_SCM_SAS.FCCIdentificationNumber",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800240 is_invasive=False,
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800241 type=TrParameterType.STRING,
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800242 is_optional=False,
243 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800244 ParameterName.SAS_MEAS_CAPS: TrParam(
245 FAP_CONTROL + "LTE.X_SCM_SAS.MeasCapability",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800246 is_invasive=False,
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800247 type=TrParameterType.STRING,
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800248 is_optional=False,
249 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800250 ParameterName.SAS_MANU_ENABLE: TrParam(
251 FAP_CONTROL + "LTE.X_SCM_SAS.ManufacturerPrefixEnable",
252 is_invasive=False,
253 type=TrParameterType.BOOLEAN,
254 is_optional=False,
255 ),
256 ParameterName.SAS_CPI_NAME: TrParam(
257 FAP_CONTROL + "LTE.X_SCM_SAS.CPIName",
258 is_invasive=False,
259 type=TrParameterType.STRING,
260 is_optional=False,
261 ),
262 ParameterName.SAS_CPI_ID: TrParam(
263 FAP_CONTROL + "LTE.X_SCM_SAS.CPIId",
264 is_invasive=False,
265 type=TrParameterType.STRING,
266 is_optional=False,
267 ),
268 ParameterName.SAS_ANTA_AZIMUTH: TrParam(
269 FAP_CONTROL + "LTE.X_SCM_SAS.AntennaAzimuth",
270 is_invasive=False,
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800271 type=TrParameterType.INT,
272 is_optional=False,
273 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800274 ParameterName.SAS_ANTA_DOWNTILT: TrParam(
275 FAP_CONTROL + "LTE.X_SCM_SAS.AntennaDowntilt",
276 is_invasive=False,
277 type=TrParameterType.INT,
278 is_optional=False,
279 ),
280 ParameterName.SAS_ANTA_GAIN: TrParam(
281 FAP_CONTROL + "LTE.X_SCM_SAS.AntennaGain",
282 is_invasive=False,
283 type=TrParameterType.INT,
284 is_optional=False,
285 ),
286 ParameterName.SAS_ANTA_BEAMWIDTH: TrParam(
287 FAP_CONTROL + "LTE.X_SCM_SAS.AntennaBeamwidth",
288 is_invasive=False,
289 type=TrParameterType.INT,
290 is_optional=False,
291 ),
292 ParameterName.SAS_CPI_DATA: TrParam(
293 FAP_CONTROL + "LTE.X_SCM_SAS.CPISignatureData",
294 is_invasive=False,
295 type=TrParameterType.STRING,
296 is_optional=False,
297 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800298 }
299
300
301class StatusParameters:
302 """
303 Stateful class that converts eNB status to Magma understood status.
304 FreedomFiOne has many status params that interact with each other.
305 This class maintains the business logic of parsing these status params
306 and converting it to Magma understood fields.
307 """
308
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800309 # Status parameters
310 DEFAULT_GW = "defaultGW"
311 SYNC_STATUS = "syncStatus"
312 SAS_STATUS = "sasStatus"
313 ENB_STATUS = "enbStatus"
314 GPS_SCAN_STATUS = "gpsScanStatus"
315
316 STATUS_PARAMETERS = {
317 # Status nodes
318 DEFAULT_GW: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800319 "Device.X_SCM_DeviceFeature.X_SCM_NEStatus.X_SCM_DEFGW_Status",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800320 is_invasive=False,
321 type=TrParameterType.STRING,
322 is_optional=False,
323 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800324 SAS_STATUS: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800325 "Device.Services.FAPService.1.FAPControl.LTE.X_SCM_SAS.State",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800326 is_invasive=False,
327 type=TrParameterType.STRING,
328 is_optional=False,
329 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800330 GPS_SCAN_STATUS: TrParam(
331 "Device.FAP.GPS.ScanStatus",
332 is_invasive=False,
333 type=TrParameterType.STRING,
334 is_optional=False,
335 ),
336 ParameterName.GPS_LAT: TrParam(
337 "Device.FAP.GPS.LockedLatitude",
338 is_invasive=False,
339 type=TrParameterType.STRING,
340 is_optional=False,
341 ),
342 ParameterName.GPS_LONG: TrParam(
343 "Device.FAP.GPS.LockedLongitude",
344 is_invasive=False,
345 type=TrParameterType.STRING,
346 is_optional=False,
347 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800348 ParameterName.SW_VERSION: TrParam(
349 "Device.DeviceInfo.SoftwareVersion",
350 is_invasive=False,
351 type=TrParameterType.STRING,
352 is_optional=False,
353 ),
354 ParameterName.SERIAL_NUMBER: TrParam(
355 "Device.DeviceInfo.SerialNumber",
356 is_invasive=False,
357 type=TrParameterType.STRING,
358 is_optional=False,
359 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800360 }
361
362 # Derived status params that don't have tr69 representation.
363 DERIVED_STATUS_PARAMETERS = {
364 ParameterName.RF_TX_STATUS: TrParam(
365 InvalidTrParamPath,
366 is_invasive=False,
367 type=TrParameterType.BOOLEAN,
368 is_optional=False,
369 ),
370 ParameterName.GPS_STATUS: TrParam(
371 InvalidTrParamPath,
372 is_invasive=False,
373 type=TrParameterType.BOOLEAN,
374 is_optional=False,
375 ),
376 ParameterName.PTP_STATUS: TrParam(
377 InvalidTrParamPath,
378 is_invasive=False,
379 type=TrParameterType.BOOLEAN,
380 is_optional=False,
381 ),
382 ParameterName.MME_STATUS: TrParam(
383 InvalidTrParamPath,
384 is_invasive=False,
385 type=TrParameterType.BOOLEAN,
386 is_optional=False,
387 ),
388 ParameterName.OP_STATE: TrParam(
389 InvalidTrParamPath,
390 is_invasive=False,
391 type=TrParameterType.BOOLEAN,
392 is_optional=False,
393 ),
394 }
395
396 @classmethod
397 def set_magma_device_cfg(
398 cls, name_to_val: Dict, device_cfg: EnodebConfiguration,
399 ):
400 """
401 Convert FreedomFiOne name_to_val representation to magma device_cfg
402 """
403 success_str = "SUCCESS" # String constant returned by radio
404 insync_str = "INSYNC"
405
406 if (
407 name_to_val.get(cls.DEFAULT_GW)
408 and name_to_val[cls.DEFAULT_GW].upper() != success_str
409 ):
410 # Nothing will proceed if the eNB doesn't have an IP on the WAN
411 serial_num = "unknown"
412 if device_cfg.has_parameter(ParameterName.SERIAL_NUMBER):
413 serial_num = device_cfg.get_parameter(ParameterName.SERIAL_NUMBER,)
414 EnodebdLogger.error(
415 "Radio with serial number %s doesn't have IP address " "on WAN",
416 serial_num,
417 )
418 device_cfg.set_parameter(
419 param_name=ParameterName.RF_TX_STATUS, value=False,
420 )
421 device_cfg.set_parameter(
422 param_name=ParameterName.GPS_STATUS, value=False,
423 )
424 device_cfg.set_parameter(
425 param_name=ParameterName.PTP_STATUS, value=False,
426 )
427 device_cfg.set_parameter(
428 param_name=ParameterName.MME_STATUS, value=False,
429 )
430 device_cfg.set_parameter(
431 param_name=ParameterName.OP_STATE, value=False,
432 )
433 return
434
435 if (
436 name_to_val.get(cls.SAS_STATUS)
437 and name_to_val[cls.SAS_STATUS].upper() == success_str
438 ):
439 device_cfg.set_parameter(
440 param_name=ParameterName.RF_TX_STATUS, value=True,
441 )
442 else:
443 # No sas grant so not transmitting. There is no explicit node for Tx
444 # in FreedomFiOne
445 device_cfg.set_parameter(
446 param_name=ParameterName.RF_TX_STATUS, value=False,
447 )
448
449 if (
450 name_to_val.get(cls.GPS_SCAN_STATUS)
451 and name_to_val[cls.GPS_SCAN_STATUS].upper() == success_str
452 ):
453 device_cfg.set_parameter(
454 param_name=ParameterName.GPS_STATUS, value=True,
455 )
456 # Time comes through GPS so can only be insync with GPS is
457 # in sync, we use PTP_STATUS field to overload timer is in Sync.
458 if (
459 name_to_val.get(cls.SYNC_STATUS)
460 and name_to_val[cls.SYNC_STATUS].upper() == insync_str
461 ):
462 device_cfg.set_parameter(
463 param_name=ParameterName.PTP_STATUS, value=True,
464 )
465 else:
466 device_cfg.set_parameter(
467 param_name=ParameterName.PTP_STATUS, value=False,
468 )
469 else:
470 device_cfg.set_parameter(
471 param_name=ParameterName.GPS_STATUS, value=False,
472 )
473 device_cfg.set_parameter(
474 param_name=ParameterName.PTP_STATUS, value=False,
475 )
476
477 if (
478 name_to_val.get(cls.DEFAULT_GW)
479 and name_to_val[cls.DEFAULT_GW].upper() == success_str
480 ):
481 device_cfg.set_parameter(
482 param_name=ParameterName.MME_STATUS, value=True,
483 )
484 else:
485 device_cfg.set_parameter(
486 param_name=ParameterName.MME_STATUS, value=False,
487 )
488
489 if (
490 name_to_val.get(cls.ENB_STATUS)
491 and name_to_val[cls.ENB_STATUS].upper() == success_str
492 ):
493 device_cfg.set_parameter(
494 param_name=ParameterName.OP_STATE, value=True,
495 )
496 else:
497 device_cfg.set_parameter(
498 param_name=ParameterName.OP_STATE, value=False,
499 )
500
501 pass_through_params = [ParameterName.GPS_LAT, ParameterName.GPS_LONG]
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800502
503 print(name_to_val)
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800504 for name in pass_through_params:
505 device_cfg.set_parameter(name, name_to_val[name])
506
507
508class FreedomFiOneMiscParameters:
509 """
510 Default set of parameters that enable carrier aggregation and other
511 miscellaneous properties
512 """
513
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800514 MISC_PARAMETERS = {
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800515 ParameterName.CARRIER_AGG_ENABLE: TrParam(
516 FAP_CONTROL + "LTE.X_SCM_RRMConfig.X_SCM_CA_Enable",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800517 is_invasive=False,
518 type=TrParameterType.BOOLEAN,
519 is_optional=False,
520 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800521 ParameterName.CARRIER_NUMBER: TrParam(
522 FAP_CONTROL + "LTE.X_SCM_RRMConfig.X_SCM_Cell_Number",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800523 is_invasive=False,
524 type=TrParameterType.INT,
525 is_optional=False,
526 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800527 ParameterName.CONTIGUOUS_CC: TrParam(
528 FAP_CONTROL + "LTE.X_SCM_RRMConfig.X_SCM_CELL_Freq_Contiguous",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800529 is_invasive=False,
530 type=TrParameterType.INT,
531 is_optional=False,
532 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800533 ParameterName.PRIM_SOURCE: TrParam(
534 FAPSERVICE_PATH + "REM.X_SCM_tfcsManagerConfig.primSrc",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800535 is_invasive=False,
536 type=TrParameterType.STRING,
537 is_optional=False,
538 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800539 ParameterName.ENABLE_CWMP: TrParam(
540 "Device.ManagementServer.EnableCWMP",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800541 is_invasive=False,
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800542 type=TrParameterType.BOOLEAN,
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800543 is_optional=False,
544 ),
545 }
546
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800547
548class FreedomFiOneTrDataModel(DataModel):
549 """
550 Class to represent relevant data model parameters from TR-196/TR-098.
551 This class is effectively read-only.
552
553 These models have these idiosyncrasies (on account of running TR098):
554
555 - Parameter content root is different (InternetGatewayDevice)
556 - GetParameter queries with a wildcard e.g. InternetGatewayDevice. do
557 not respond with the full tree (we have to query all parameters)
558 - MME status is not exposed - we assume the MME is connected if
559 the eNodeB is transmitting (OpState=true)
560 - Parameters such as band capability/duplex config
561 are rooted under `boardconf.` and not the device config root
562 - Num PLMNs is not reported by these units
563 """
564
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800565 PARAMETERS = {
566 # Top-level objects
567 ParameterName.DEVICE: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800568 "Device.",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800569 is_invasive=False,
570 type=TrParameterType.OBJECT,
571 is_optional=False,
572 ),
573 ParameterName.FAP_SERVICE: TrParam(
574 FAP_CONTROL,
575 is_invasive=False,
576 type=TrParameterType.OBJECT,
577 is_optional=False,
578 ),
579 # Device info
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800580 ParameterName.IP_ADDRESS: TrParam(
581 "Device.IP.Interface.1.IPv4Address.1.IPAddress",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800582 is_invasive=False,
583 type=TrParameterType.STRING,
584 is_optional=False,
585 ),
586 # RF-related parameters
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800587 ParameterName.FREQ_BAND_1: TrParam(
588 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.FreqBandIndicator",
589 is_invasive=False,
590 type=TrParameterType.UNSIGNED_INT,
591 is_optional=False,
592 ),
593 ParameterName.FREQ_BAND_2: TrParam(
594 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_FreqBandIndicator2",
595 is_invasive=False,
596 type=TrParameterType.UNSIGNED_INT,
597 is_optional=False,
598 ),
599 ParameterName.FREQ_BAND_LIST: TrParam(
600 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_FreqBandIndicatorConfigList",
601 is_invasive=False,
602 type=TrParameterType.STRING,
603 is_optional=False,
604 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800605 ParameterName.EARFCNDL: TrParam(
606 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.EARFCNDL",
607 is_invasive=False,
608 type=TrParameterType.INT,
609 is_optional=False,
610 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800611 ParameterName.EARFCNUL: TrParam(
612 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.EARFCNUL",
613 is_invasive=False,
614 type=TrParameterType.INT,
615 is_optional=False,
616 ),
617 ParameterName.EARFCNDL2: TrParam(
618 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_EARFCNDL2",
619 is_invasive=False,
620 type=TrParameterType.INT,
621 is_optional=False,
622 ),
623 ParameterName.EARFCNUL2: TrParam(
624 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_EARFCNUL2",
625 is_invasive=False,
626 type=TrParameterType.INT,
627 is_optional=False,
628 ),
629 ParameterName.EARFCNDL_LIST: TrParam(
630 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_EARFCNDLConfigList",
631 is_invasive=False,
632 type=TrParameterType.STRING,
633 is_optional=False,
634 ),
635 ParameterName.EARFCNUL_LIST: TrParam(
636 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_EARFCNULConfigList",
637 is_invasive=False,
638 type=TrParameterType.STRING,
639 is_optional=False,
640 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800641 ParameterName.DL_BANDWIDTH: TrParam(
642 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.DLBandwidth",
643 is_invasive=False,
644 type=TrParameterType.STRING,
645 is_optional=False,
646 ),
647 ParameterName.UL_BANDWIDTH: TrParam(
648 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.ULBandwidth",
649 is_invasive=False,
650 type=TrParameterType.STRING,
651 is_optional=False,
652 ),
653 ParameterName.PCI: TrParam(
654 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.PhyCellID",
655 is_invasive=False,
656 type=TrParameterType.STRING,
657 is_optional=False,
658 ),
659 ParameterName.SUBFRAME_ASSIGNMENT: TrParam(
660 FAPSERVICE_PATH + "CellConfig.LTE.RAN.PHY.TDDFrame.SubFrameAssignment",
661 is_invasive=False,
662 type=TrParameterType.BOOLEAN,
663 is_optional=False,
664 ),
665 ParameterName.SPECIAL_SUBFRAME_PATTERN: TrParam(
666 FAPSERVICE_PATH + "CellConfig.LTE.RAN.PHY.TDDFrame.SpecialSubframePatterns",
667 is_invasive=False,
668 type=TrParameterType.INT,
669 is_optional=False,
670 ),
671 ParameterName.CELL_ID: TrParam(
672 FAPSERVICE_PATH + "CellConfig.LTE.RAN.Common.CellIdentity",
673 is_invasive=False,
674 type=TrParameterType.UNSIGNED_INT,
675 is_optional=False,
676 ),
677 # Readonly LTE state
678 ParameterName.ADMIN_STATE: TrParam(
679 FAP_CONTROL + "LTE.AdminState",
680 is_invasive=False,
681 type=TrParameterType.BOOLEAN,
682 is_optional=False,
683 ),
684 ParameterName.GPS_ENABLE: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800685 "Device.FAP.GPS.ScanOnBoot",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800686 is_invasive=False,
687 type=TrParameterType.BOOLEAN,
688 is_optional=False,
689 ),
690 # Core network parameters
691 ParameterName.MME_IP: TrParam(
692 FAP_CONTROL + "LTE.Gateway.S1SigLinkServerList",
693 is_invasive=False,
694 type=TrParameterType.STRING,
695 is_optional=False,
696 ),
697 ParameterName.MME_PORT: TrParam(
698 FAP_CONTROL + "LTE.Gateway.S1SigLinkPort",
699 is_invasive=False,
700 type=TrParameterType.INT,
701 is_optional=False,
702 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800703 ParameterName.TAC: TrParam(
704 FAPSERVICE_PATH + "CellConfig.LTE.EPC.TAC",
705 is_invasive=False,
706 type=TrParameterType.INT,
707 is_optional=False,
708 ),
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800709 ParameterName.TAC2: TrParam(
710 FAPSERVICE_PATH + "CellConfig.LTE.EPC.X_SCM_TAC2",
711 is_invasive=False,
712 type=TrParameterType.INT,
713 is_optional=False,
714 ),
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800715 # Management server parameters
716 ParameterName.PERIODIC_INFORM_ENABLE: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800717 "Device.ManagementServer.PeriodicInformEnable",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800718 is_invasive=False,
719 type=TrParameterType.BOOLEAN,
720 is_optional=False,
721 ),
722 ParameterName.PERIODIC_INFORM_INTERVAL: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800723 "Device.ManagementServer.PeriodicInformInterval",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800724 is_invasive=False,
725 type=TrParameterType.INT,
726 is_optional=False,
727 ),
728 # Performance management parameters
729 ParameterName.PERF_MGMT_ENABLE: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800730 "Device.FAP.PerfMgmt.Config.1.Enable",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800731 is_invasive=False,
732 type=TrParameterType.BOOLEAN,
733 is_optional=False,
734 ),
735 ParameterName.PERF_MGMT_UPLOAD_INTERVAL: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800736 "Device.FAP.PerfMgmt.Config.1.PeriodicUploadInterval",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800737 is_invasive=False,
738 type=TrParameterType.INT,
739 is_optional=False,
740 ),
741 ParameterName.PERF_MGMT_UPLOAD_URL: TrParam(
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800742 "Device.FAP.PerfMgmt.Config.1.URL",
743 is_invasive=False,
744 type=TrParameterType.STRING,
745 is_optional=False,
746 ),
747 ParameterName.TX_POWER: TrParam(
748 FAPSERVICE_PATH + "CellConfig.LTE.RAN.RF.X_SCM_TxPowerConfig",
749 is_invasive=True,
750 type=TrParameterType.INT,
751 is_optional=False,
752 ),
753 ParameterName.TUNNEL_TYPE: TrParam(
754 FAPSERVICE_PATH + "CellConfig.LTE.Tunnel.1.TunnelRef",
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800755 is_invasive=False,
756 type=TrParameterType.STRING,
757 is_optional=False,
758 ),
759 }
760 TRANSFORMS_FOR_ENB = {}
761 NUM_PLMNS_IN_CONFIG = 1
762 for i in range(1, NUM_PLMNS_IN_CONFIG + 1):
763 PARAMETERS[ParameterName.PLMN_N % i] = TrParam(
764 FAPSERVICE_PATH + "CellConfig.LTE.EPC.PLMNList.%d." % i,
765 is_invasive=False,
766 type=TrParameterType.STRING,
767 is_optional=False,
768 )
769 PARAMETERS[ParameterName.PLMN_N_CELL_RESERVED % i] = TrParam(
770 FAPSERVICE_PATH
771 + "CellConfig.LTE.EPC.PLMNList.%d.CellReservedForOperatorUse" % i,
772 is_invasive=False,
773 type=TrParameterType.BOOLEAN,
774 is_optional=False,
775 )
776 PARAMETERS[ParameterName.PLMN_N_ENABLE % i] = TrParam(
777 FAPSERVICE_PATH + "CellConfig.LTE.EPC.PLMNList.%d.Enable" % i,
778 is_invasive=False,
779 type=TrParameterType.BOOLEAN,
780 is_optional=False,
781 )
782 PARAMETERS[ParameterName.PLMN_N_PRIMARY % i] = TrParam(
783 FAPSERVICE_PATH + "CellConfig.LTE.EPC.PLMNList.%d.IsPrimary" % i,
784 is_invasive=False,
785 type=TrParameterType.BOOLEAN,
786 is_optional=False,
787 )
788 PARAMETERS[ParameterName.PLMN_N_PLMNID % i] = TrParam(
789 FAPSERVICE_PATH + "CellConfig.LTE.EPC.PLMNList.%d.PLMNID" % i,
790 is_invasive=False,
791 type=TrParameterType.STRING,
792 is_optional=False,
793 )
794
795 PARAMETERS.update(SASParameters.SAS_PARAMETERS)
796 PARAMETERS.update(FreedomFiOneMiscParameters.MISC_PARAMETERS)
797 PARAMETERS.update(StatusParameters.STATUS_PARAMETERS)
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800798 PARAMETERS.update(StatusParameters.DERIVED_STATUS_PARAMETERS)
799
800 TRANSFORMS_FOR_MAGMA = {
801 # We don't set these parameters
802 ParameterName.BAND_CAPABILITY: transform_for_magma.band_capability,
803 ParameterName.DUPLEX_MODE_CAPABILITY: transform_for_magma.duplex_mode,
804 }
805
806 @classmethod
807 def get_parameter(cls, param_name: ParameterName) -> Optional[TrParam]:
808 return cls.PARAMETERS.get(param_name)
809
810 @classmethod
811 def _get_magma_transforms(cls,) -> Dict[ParameterName, Callable[[Any], Any]]:
812 return cls.TRANSFORMS_FOR_MAGMA
813
814 @classmethod
815 def _get_enb_transforms(cls) -> Dict[ParameterName, Callable[[Any], Any]]:
816 return cls.TRANSFORMS_FOR_ENB
817
818 @classmethod
819 def get_load_parameters(cls) -> List[ParameterName]:
820 """
821 Load all the parameters instead of a subset.
822 """
823 return list(cls.PARAMETERS.keys())
824
825 @classmethod
826 def get_num_plmns(cls) -> int:
827 return cls.NUM_PLMNS_IN_CONFIG
828
829 @classmethod
830 def get_parameter_names(cls) -> List[ParameterName]:
831 excluded_params = [
832 str(ParameterName.DEVICE),
833 str(ParameterName.FAP_SERVICE),
834 ]
835 names = list(
836 filter(
837 lambda x: (not str(x).startswith("PLMN"))
838 and (str(x) not in excluded_params),
839 cls.PARAMETERS.keys(),
840 ),
841 )
842 return names
843
844 @classmethod
845 def get_numbered_param_names(cls,) -> Dict[ParameterName, List[ParameterName]]:
846 names = {}
847 for i in range(1, cls.NUM_PLMNS_IN_CONFIG + 1):
848 params = [
849 ParameterName.PLMN_N_CELL_RESERVED % i,
850 ParameterName.PLMN_N_ENABLE % i,
851 ParameterName.PLMN_N_PRIMARY % i,
852 ParameterName.PLMN_N_PLMNID % i,
853 ]
854 names[ParameterName.PLMN_N % i] = params
855
856 return names
857
858 @classmethod
859 def get_sas_param_names(cls) -> List[ParameterName]:
860 return SASParameters.SAS_PARAMETERS.keys()
861
862
863class FreedomFiOneConfigurationInitializer(EnodebConfigurationPostProcessor):
864 """
865 Class to add the sas related parameters to the desired config.
866 """
867
868 SAS_KEY = "sas"
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800869
870 def __init__(self, acs: EnodebAcsStateMachine):
871 super().__init__()
872 self.acs = acs
873
874 def postprocess(
875 self, mconfig: Any, service_cfg: Any, desired_cfg: EnodebConfiguration,
876 ) -> None:
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800877 # Bump up the parameter key version
878 self.acs.parameter_version_inc()
879
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +0800880 # Load eNB customized configuration from "./magma_config/serial_number/"
881 # and configure each connected eNB based on serial number
882 enbcfg = load_enb_config()
883 sn = self.acs.get_parameter(ParameterName.SERIAL_NUMBER)
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800884
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +0800885 for name, val in enbcfg.get(sn, {}).items():
886 # The SAS configuration for eNodeB
887 if name in ["sas", "cell"]:
888 for subname, subval in val.items():
889 print("Config %s updated to: %s" % (subname, subval))
890 desired_cfg.set_parameter(subname, subval)
891
892 print(desired_cfg)
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800893
894
895class FreedomFiOneSendGetTransientParametersState(EnodebAcsState):
896 """
897 Periodically read eNodeB status. Note: keep frequency low to avoid
898 backing up large numbers of read operations if enodebd is busy.
899 Some eNB parameters are read only and updated by the eNB itself.
900 """
901
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800902 def __init__(self, acs: EnodebAcsStateMachine, when_upgrade: str, when_done: str):
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800903 super().__init__()
904 self.acs = acs
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800905 self.upgrade_transition = when_upgrade
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800906 self.done_transition = when_done
907
908 def get_msg(self, message: Any) -> AcsMsgAndTransition:
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +0800909
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800910 request = models.GetParameterValues()
911 request.ParameterNames = models.ParameterNames()
912 request.ParameterNames.string = []
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +0800913
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800914 for _, tr_param in StatusParameters.STATUS_PARAMETERS.items():
915 path = tr_param.path
916 request.ParameterNames.string.append(path)
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +0800917
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800918 request.ParameterNames.arrayType = "xsd:string[%d]" % len(
919 request.ParameterNames.string
920 )
921
922 return AcsMsgAndTransition(msg=request, next_state=None)
923
924 def read_msg(self, message: Any) -> AcsReadMsgResult:
925
926 if not isinstance(message, models.GetParameterValuesResponse):
927 return AcsReadMsgResult(msg_handled=False, next_state=None)
928 # Current values of the fetched parameters
929 name_to_val = parse_get_parameter_values_response(self.acs.data_model, message,)
930 EnodebdLogger.debug("Received Parameters: %s", str(name_to_val))
931
932 # Update device configuration
933 StatusParameters.set_magma_device_cfg(
934 name_to_val, self.acs.device_cfg,
935 )
936
Wei-Yu Chen678f0a52021-12-21 13:50:52 +0800937 print("In get transient state", name_to_val, type(name_to_val))
938 if name_to_val["SW version"] != "TEST3918@210224":
939 print("Get into Firmware Upgrade state")
940 return AcsReadMsgResult(
941 msg_handled=True, next_state=self.upgrade_transition
942 )
943
944 print("Skip firmware upgrade, configure the enb")
945 return AcsReadMsgResult(msg_handled=True, next_state=self.done_transition)
Wei-Yu Chen49950b92021-11-08 19:19:18 +0800946
947 def state_description(self) -> str:
948 return "Getting transient read-only parameters"
949
950
951class FreedomFiOneGetInitState(EnodebAcsState):
952 """
953 After the first Inform message the following can happen:
954 1 - eNB can try to learn the RPC method of the ACS, reply back with the
955 RPC response (happens right after boot)
956 2 - eNB can send an empty message -> This means that the eNB is already
957 provisioned so transition to next state. Only transition to next state
958 after this message.
959 3 - Some other method call that we don't care about so ignore.
960 expected that the eNB -> This is an unhandled state so unlikely
961 """
962
963 def __init__(self, acs: EnodebAcsStateMachine, when_done):
964 super().__init__()
965 self.acs = acs
966 self.done_transition = when_done
967 self._is_rpc_request = False
968
969 def get_msg(self, message: Any) -> AcsMsgAndTransition:
970 """
971 Return empty message response if care about this
972 message type otherwise return empty RPC methods response.
973 """
974 if not self._is_rpc_request:
975 resp = models.DummyInput()
976 return AcsMsgAndTransition(msg=resp, next_state=None)
977
978 resp = models.GetRPCMethodsResponse()
979 resp.MethodList = models.MethodList()
980 RPC_METHODS = ["Inform", "GetRPCMethods", "TransferComplete"]
981 resp.MethodList.arrayType = "xsd:string[%d]" % len(RPC_METHODS)
982 resp.MethodList.string = RPC_METHODS
983 # Don't transition to next state wait for the empty HTTP post
984 return AcsMsgAndTransition(msg=resp, next_state=None)
985
986 def read_msg(self, message: Any) -> AcsReadMsgResult:
987 # If this is a regular Inform, not after a reboot we'll get an empty
988 # message, in this case transition to the next state. We consider
989 # this phase as "initialized"
990 if isinstance(message, models.DummyInput):
991 return AcsReadMsgResult(msg_handled=True, next_state=self.done_transition,)
992 if not isinstance(message, models.GetRPCMethods):
993 # Unexpected, just don't die, ignore message.
994 logging.error("Ignoring message %s", str(type(message)))
995 # Set this so get_msg will return an empty message
996 self._is_rpc_request = False
997 else:
998 # Return a valid RPC response
999 self._is_rpc_request = True
1000 return AcsReadMsgResult(msg_handled=True, next_state=None)
1001
1002 def state_description(self) -> str:
1003 return "Initializing the post boot sequence for eNB"
1004
1005
1006class FreedomFiOneGetObjectParametersState(EnodebAcsState):
1007 """
1008 Get information on parameters belonging to objects that can be added or
1009 removed from the configuration.
1010
1011 Englewood will report a parameter value as None if it does not exist
1012 in the data model, rather than replying with a Fault message like most
1013 eNB devices.
1014 """
1015
1016 def __init__(
1017 self,
1018 acs: EnodebAcsStateMachine,
1019 when_delete: str,
1020 when_add: str,
1021 when_set: str,
1022 when_skip: str,
1023 ):
1024 super().__init__()
1025 self.acs = acs
1026 self.rm_obj_transition = when_delete
1027 self.add_obj_transition = when_add
1028 self.set_params_transition = when_set
1029 self.skip_transition = when_skip
1030
1031 def get_params_to_get(self, data_model: DataModel,) -> List[ParameterName]:
1032 names = []
1033
1034 # First get base params
1035 names = get_params_to_get(
1036 self.acs.device_cfg, self.acs.data_model, request_all_params=True,
1037 )
1038 # Add object params.
1039 num_plmns = data_model.get_num_plmns()
1040 obj_to_params = data_model.get_numbered_param_names()
1041 for i in range(1, num_plmns + 1):
1042 obj_name = ParameterName.PLMN_N % i
1043 desired = obj_to_params[obj_name]
1044 names += desired
Wei-Yu Chen678f0a52021-12-21 13:50:52 +08001045
1046 print(obj_to_params)
Wei-Yu Chen49950b92021-11-08 19:19:18 +08001047 return names
1048
1049 def get_msg(self, message: Any) -> AcsMsgAndTransition:
1050 """ Respond with GetParameterValuesRequest """
1051 names = self.get_params_to_get(self.acs.data_model,)
1052
1053 # Generate the request
1054 request = models.GetParameterValues()
1055 request.ParameterNames = models.ParameterNames()
1056 request.ParameterNames.arrayType = "xsd:string[%d]" % len(names)
1057 request.ParameterNames.string = []
1058 for name in names:
1059 path = self.acs.data_model.get_parameter(name).path
1060 if path is not InvalidTrParamPath:
1061 # Only get data elements backed by tr69 path
1062 request.ParameterNames.string.append(path)
1063
1064 return AcsMsgAndTransition(msg=request, next_state=None)
1065
1066 def read_msg(self, message: Any) -> AcsReadMsgResult:
1067 """
1068 Process GetParameterValuesResponse
1069 """
1070 if not isinstance(message, models.GetParameterValuesResponse):
1071 return AcsReadMsgResult(msg_handled=False, next_state=None)
1072
1073 path_to_val = {}
1074 for param_value_struct in message.ParameterList.ParameterValueStruct:
1075 path_to_val[param_value_struct.Name] = param_value_struct.Value.Data
1076
1077 EnodebdLogger.debug("Received object parameters: %s", str(path_to_val))
1078
1079 # Parse simple params
1080 param_name_list = self.acs.data_model.get_parameter_names()
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +08001081
Wei-Yu Chen49950b92021-11-08 19:19:18 +08001082 for name in param_name_list:
1083 path = self.acs.data_model.get_parameter(name).path
1084 if path in path_to_val:
1085 value = path_to_val.get(path)
1086 magma_val = self.acs.data_model.transform_for_magma(name, value,)
1087 self.acs.device_cfg.set_parameter(name, magma_val)
1088
1089 # Parse object params
1090 num_plmns = self.acs.data_model.get_num_plmns()
1091 for i in range(1, num_plmns + 1):
1092 obj_name = ParameterName.PLMN_N % i
1093 obj_to_params = self.acs.data_model.get_numbered_param_names()
1094 param_name_list = obj_to_params[obj_name]
1095 for name in param_name_list:
1096 path = self.acs.data_model.get_parameter(name).path
1097 if path in path_to_val:
1098 value = path_to_val.get(path)
1099 if value is None:
1100 continue
1101 if obj_name not in self.acs.device_cfg.get_object_names():
1102 self.acs.device_cfg.add_object(obj_name)
1103 magma_value = self.acs.data_model.transform_for_magma(name, value)
1104 self.acs.device_cfg.set_parameter_for_object(
1105 name, magma_value, obj_name,
1106 )
Wei-Yu Chen5cbdfbb2021-12-02 01:10:21 +08001107
Wei-Yu Chen49950b92021-11-08 19:19:18 +08001108 # Now we have enough information to build the desired configuration
1109 if self.acs.desired_cfg is None:
1110 self.acs.desired_cfg = build_desired_config(
1111 self.acs.mconfig,
1112 self.acs.service_config,
1113 self.acs.device_cfg,
1114 self.acs.data_model,
1115 self.acs.config_postprocessor,
1116 )
1117
1118 if (
1119 len(get_all_objects_to_delete(self.acs.desired_cfg, self.acs.device_cfg,),)
1120 > 0
1121 ):
1122 return AcsReadMsgResult(
1123 msg_handled=True, next_state=self.rm_obj_transition,
1124 )
1125 elif (
1126 len(get_all_objects_to_add(self.acs.desired_cfg, self.acs.device_cfg,),) > 0
1127 ):
1128 return AcsReadMsgResult(
1129 msg_handled=True, next_state=self.add_obj_transition,
1130 )
1131 elif (
1132 len(
1133 get_all_param_values_to_set(
1134 self.acs.desired_cfg, self.acs.device_cfg, self.acs.data_model,
1135 ),
1136 )
1137 > 0
1138 ):
1139 return AcsReadMsgResult(
1140 msg_handled=True, next_state=self.set_params_transition,
1141 )
1142 return AcsReadMsgResult(msg_handled=True, next_state=self.skip_transition,)
1143
1144 def state_description(self) -> str:
1145 return "Getting well known parameters"