blob: 2f5f656fb7ac20f49a9cb1d7335af35178d71021 [file] [log] [blame]
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001/*
Joey Armstrong89c812c2024-01-12 19:00:20 -05002 * Copyright 2020-2024 Open Networking Foundation (ONF) and the ONF Contributors
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
nikesh.krishnan1249be92023-11-27 04:20:12 +053017// Package mib provides the utilities for managing the onu mib
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000018package mib
19
20import (
21 "context"
22 "encoding/json"
23 "errors"
24 "fmt"
Holger Hildebrandtc56febd2022-02-09 13:23:30 +000025 "strconv"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000026 "sync"
27 "time"
28
29 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000030 "github.com/opencord/omci-lib-go/v2"
31 me "github.com/opencord/omci-lib-go/v2/generated"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000032 "github.com/opencord/voltha-lib-go/v7/pkg/db"
33 "github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
Holger Hildebrandtc56febd2022-02-09 13:23:30 +000034 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000035 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
Holger Hildebrandt9afc1582021-11-30 16:10:19 +000036 "github.com/opencord/voltha-protos/v5/go/inter_adapter"
Holger Hildebrandtc56febd2022-02-09 13:23:30 +000037 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000038
39 "github.com/opencord/voltha-lib-go/v7/pkg/log"
40
41 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
42 devdb "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/devdb"
43 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/swupg"
44)
45
46// events of MibUpload FSM
47const (
48 UlEvStart = "UlEvStart"
49 UlEvResetMib = "UlEvResetMib"
50 UlEvGetVendorAndSerial = "UlEvGetVendorAndSerial"
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +000051 UlEvGetVersion = "UlEvGetVersion"
Holger Hildebrandta6ef0e82022-04-06 13:11:32 +000052 UlEvGetEquipIDAndOmcc = "UlEvGetEquipIDAndOmcc"
53 UlEvTestExtOmciSupport = "UlEvTestExtOmciSupport"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000054 UlEvGetFirstSwVersion = "UlEvGetFirstSwVersion"
55 UlEvGetSecondSwVersion = "UlEvGetSecondSwVersion"
56 UlEvGetMacAddress = "UlEvGetMacAddress"
57 UlEvGetMibTemplate = "UlEvGetMibTemplate"
58 UlEvUploadMib = "UlEvUploadMib"
Holger Hildebrandt9afc1582021-11-30 16:10:19 +000059 UlEvVerifyAndStoreTPs = "UlEvVerifyAndStoreTPs"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000060 UlEvExamineMds = "UlEvExamineMds"
61 UlEvSuccess = "UlEvSuccess"
62 UlEvMismatch = "UlEvMismatch"
63 UlEvAuditMib = "UlEvAuditMib"
64 UlEvForceResync = "UlEvForceResync"
65 UlEvDiffsFound = "UlEvDiffsFound"
66 UlEvTimeout = "UlEvTimeout"
67 UlEvStop = "UlEvStop"
68)
69
70// states of MibUpload FSM
71const (
72 UlStDisabled = "UlStDisabled"
73 UlStStarting = "UlStStarting"
74 UlStResettingMib = "UlStResettingMib"
75 UlStGettingVendorAndSerial = "UlStGettingVendorAndSerial"
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +000076 UlStGettingVersion = "UlStGettingVersion"
Holger Hildebrandta6ef0e82022-04-06 13:11:32 +000077 UlStGettingEquipIDAndOmcc = "UlStGettingEquipIDAndOmcc"
78 UlStTestingExtOmciSupport = "UlStTestingExtOmciSupport"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000079 UlStGettingFirstSwVersion = "UlStGettingFirstSwVersion"
80 UlStGettingSecondSwVersion = "UlStGettingSecondSwVersion"
81 UlStGettingMacAddress = "UlStGettingMacAddress"
82 UlStGettingMibTemplate = "UlStGettingMibTemplate"
83 UlStUploading = "UlStUploading"
84 UlStUploadDone = "UlStUploadDone"
85 UlStInSync = "UlStInSync"
Holger Hildebrandt9afc1582021-11-30 16:10:19 +000086 UlStVerifyingAndStoringTPs = "UlStVerifyingAndStoringTPs"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000087 UlStExaminingMds = "UlStExaminingMds"
88 UlStResynchronizing = "UlStResynchronizing"
89 UlStExaminingMdsSuccess = "UlStExaminingMdsSuccess"
90 UlStAuditing = "UlStAuditing"
91 UlStReAuditing = "UlStReAuditing"
92 UlStOutOfSync = "UlStOutOfSync"
93)
94
95// CMibUlFsmIdleState - TODO: add comment
96const CMibUlFsmIdleState = UlStInSync
97
98// events of MibDownload FSM
99const (
100 DlEvStart = "DlEvStart"
101 DlEvCreateGal = "DlEvCreateGal"
102 DlEvRxGalResp = "DlEvRxGalResp"
103 DlEvRxOnu2gResp = "DlEvRxOnu2gResp"
104 DlEvRxBridgeResp = "DlEvRxBridgeResp"
105 DlEvTimeoutSimple = "DlEvTimeoutSimple"
106 DlEvTimeoutBridge = "DlEvTimeoutBridge"
107 DlEvReset = "DlEvReset"
108 DlEvRestart = "DlEvRestart"
109)
110
111// states of MibDownload FSM
112const (
113 DlStDisabled = "DlStDisabled"
114 DlStStarting = "DlStStarting"
115 DlStCreatingGal = "DlStCreatingGal"
116 DlStSettingOnu2g = "DlStSettingOnu2g"
117 DlStBridgeInit = "DlStBridgeInit"
118 DlStDownloaded = "DlStDownloaded"
119 DlStResetting = "DlStResetting"
120)
121
122// CMibDlFsmIdleState - TODO: add comment
123const CMibDlFsmIdleState = DlStDisabled
124
125const (
126 // NOTE that this hardcoded to service/voltha as the MIB template is shared across stacks
127 cBasePathMibTemplateKvStore = "service/voltha/omci_mibs/go_templates"
128 cSuffixMibTemplateKvStore = "%s/%s/%s"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000129)
130
Holger Hildebrandtfdb4bba2022-03-10 12:12:59 +0000131const cEmptyVendorIDString = "____"
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +0000132const cEmptyVersionString = "______________"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000133const cEmptyMacAddrString = "000000000000"
134const cEmptySerialNumberString = "0000000000000000"
Holger Hildebrandtfdb4bba2022-03-10 12:12:59 +0000135const cEmptyEquipIDString = "EMPTY_EQUIP_ID"
136const cNotPresentEquipIDString = "NOT_PRESENT_EQUIP_ID"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000137
138type uniPersConfig struct {
139 PersUniID uint8 `json:"uni_id"`
140 PersTpPathMap map[uint8]string `json:"PersTpPathMap"` // tp-id to tp-path map
141 PersFlowParams []cmn.UniVlanFlowParams `json:"flow_params"` //as defined in omci_ani_config.go
142}
143
144type onuPersistentData struct {
145 PersOnuID uint32 `json:"onu_id"`
146 PersIntfID uint32 `json:"intf_id"`
147 PersSerialNumber string `json:"serial_number"`
148 PersMacAddress string `json:"mac_address"`
149 PersVendorID string `json:"vendor_id"`
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +0000150 PersVersion string `json:"version"`
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000151 PersEquipmentID string `json:"equipment_id"`
Holger Hildebrandta6ef0e82022-04-06 13:11:32 +0000152 PersIsExtOmciSupported bool `json:"is_ext_omci_supported"`
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000153 PersActiveSwVersion string `json:"active_sw_version"`
154 PersAdminState string `json:"admin_state"`
155 PersOperState string `json:"oper_state"`
156 PersUniUnlockDone bool `json:"uni_unlock_done"`
157 PersUniDisableDone bool `json:"uni_disable_done"`
158 PersMibAuditInterval time.Duration `json:"mib_audit_interval"`
159 PersMibLastDbSync uint32 `json:"mib_last_db_sync"`
160 PersMibDataSyncAdpt uint8 `json:"mib_data_sync_adpt"`
161 PersUniConfig []uniPersConfig `json:"uni_config"`
162 PersAlarmAuditInterval time.Duration `json:"alarm_audit_interval"`
163 PersTcontMap map[uint16]uint16 `json:"tcont_map"` //alloc-id to me-instance-id map
164}
165
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000166//type UniTpidInstances map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage
167
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000168// OnuDeviceEntry - ONU device info and FSM events.
169type OnuDeviceEntry struct {
170 deviceID string
171 baseDeviceHandler cmn.IdeviceHandler
Holger Hildebrandtc56febd2022-02-09 13:23:30 +0000172 eventProxy eventif.EventProxy
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000173 pOpenOnuAc cmn.IopenONUAC
174 pOnuTP cmn.IonuUniTechProf
175 coreClient *vgrpc.Client
176 PDevOmciCC *cmn.OmciCC
177 pOnuDB *devdb.OnuDeviceDB
178 mibTemplateKVStore *db.Backend
179 MutexPersOnuConfig sync.RWMutex
180 SOnuPersistentData onuPersistentData
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000181 ReconciledTpInstances map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage
182 MutexReconciledTpInstances sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000183 reconcilingFlows bool
184 mutexReconcilingFlowsFlag sync.RWMutex
185 chReconcilingFlowsFinished chan bool //channel to indicate that reconciling of flows has been finished
186 mibTemplatePath string
187 mutexOnuKVStore sync.RWMutex
188 onuKVStore *db.Backend
189 onuKVStorePath string
190 mutexOnuKVStoreProcResult sync.RWMutex
191 onuKVStoreProcResult error //error indication of processing
192 chOnuKvProcessingStep chan uint8
193 mutexOnuSwImageIndications sync.RWMutex
194 onuSwImageIndications cmn.SswImageIndications
195 MutexOnuImageStatus sync.RWMutex
196 POnuImageStatus *swupg.OnuImageStatus
197 //lockDeviceEntries sync.RWMutex
198 mibDbClass func(context.Context) error
199 supportedFsms cmn.OmciDeviceFsms
200 devState cmn.OnuDeviceEvent
201 // Audit and MDS
202 mibAuditInterval time.Duration
203 alarmAuditInterval time.Duration
204 // TODO: periodical mib resync will be implemented with story VOL-3792
205 //mibNextDbResync uint32
206
207 // for mibUpload
Girish Gowdra37c9d912022-02-08 16:24:57 -0800208 PMibUploadFsm *cmn.AdapterFsm //could be handled dynamically and more general as pcmn.AdapterFsm - perhaps later
209 mutexLastTxParamStruct sync.RWMutex
210 lastTxParamStruct sLastTxMeParameter
211 mibSyncMsgProcessorRunning bool
212 mutexMibSyncMsgProcessorRunning sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000213 // for mibDownload
214 PMibDownloadFsm *cmn.AdapterFsm //could be handled dynamically and more general as pcmn.AdapterFsm - perhaps later
215 //remark: general usage of pAdapterFsm would require generalization of CommChan usage and internal event setting
216 // within the FSM event procedures
217 mutexPLastTxMeInstance sync.RWMutex
218 pLastTxMeInstance *me.ManagedEntity
219 omciMessageReceived chan bool //seperate channel needed by DownloadFsm
220 omciRebootMessageReceivedChannel chan cmn.Message // channel needed by reboot request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000221}
222
nikesh.krishnan1249be92023-11-27 04:20:12 +0530223// NewOnuDeviceEntry returns a new instance of a OnuDeviceEntry
224// mib_db (as well as not inluded alarm_db not really used in this code? VERIFY!!)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000225func NewOnuDeviceEntry(ctx context.Context, cc *vgrpc.Client, dh cmn.IdeviceHandler,
226 openonu cmn.IopenONUAC) *OnuDeviceEntry {
227 var onuDeviceEntry OnuDeviceEntry
228 onuDeviceEntry.deviceID = dh.GetDeviceID()
229 logger.Debugw(ctx, "init-onuDeviceEntry", log.Fields{"device-id": onuDeviceEntry.deviceID})
230 onuDeviceEntry.baseDeviceHandler = dh
Holger Hildebrandtc56febd2022-02-09 13:23:30 +0000231 onuDeviceEntry.eventProxy = dh.GetEventProxy()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000232 onuDeviceEntry.pOpenOnuAc = openonu
233 onuDeviceEntry.coreClient = cc
234 onuDeviceEntry.devState = cmn.DeviceStatusInit
235 onuDeviceEntry.SOnuPersistentData.PersUniConfig = make([]uniPersConfig, 0)
236 onuDeviceEntry.SOnuPersistentData.PersTcontMap = make(map[uint16]uint16)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000237 onuDeviceEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000238 onuDeviceEntry.chReconcilingFlowsFinished = make(chan bool)
239 onuDeviceEntry.reconcilingFlows = false
240 onuDeviceEntry.chOnuKvProcessingStep = make(chan uint8)
241 onuDeviceEntry.omciRebootMessageReceivedChannel = make(chan cmn.Message, 2048)
242 //openomciagent.lockDeviceHandlersMap = sync.RWMutex{}
243 //OMCI related databases are on a per-agent basis. State machines and tasks
244 //are per ONU Vendor
245 //
246 // MIB Synchronization Database - possible overloading from arguments
247 supportedFsms := onuDeviceEntry.pOpenOnuAc.GetSupportedFsms()
248 if supportedFsms != nil {
249 onuDeviceEntry.supportedFsms = *supportedFsms
250 } else {
251 // This branch is currently not used and is for potential future usage of alternative MIB Sync FSMs only!
252 //var mibSyncFsm = NewMibSynchronizer()
253 // use some internal defaults, if not defined from outside
254 onuDeviceEntry.supportedFsms = cmn.OmciDeviceFsms{
255 "mib-synchronizer": {
256 //mibSyncFsm, // Implements the MIB synchronization state machine
257 DatabaseClass: onuDeviceEntry.mibDbVolatileDict, // Implements volatile ME MIB database
258 //true, // Advertise events on OpenOMCI event bus
259 AuditInterval: dh.GetAlarmAuditInterval(), // Time to wait between MIB audits. 0 to disable audits.
260 // map[string]func() error{
261 // "mib-upload": onuDeviceEntry.MibUploadTask,
262 // "mib-template": onuDeviceEntry.MibTemplateTask,
263 // "get-mds": onuDeviceEntry.GetMdsTask,
264 // "mib-audit": onuDeviceEntry.GetMdsTask,
265 // "mib-resync": onuDeviceEntry.MibResyncTask,
266 // "mib-reconcile": onuDeviceEntry.MibReconcileTask,
267 // },
268 },
269 }
270 }
271 onuDeviceEntry.mibDbClass = onuDeviceEntry.supportedFsms["mib-synchronizer"].DatabaseClass
272 logger.Debug(ctx, "access2mibDbClass")
273 go onuDeviceEntry.mibDbClass(ctx)
274 if !dh.IsReconciling() {
275 onuDeviceEntry.mibAuditInterval = onuDeviceEntry.supportedFsms["mib-synchronizer"].AuditInterval
276 onuDeviceEntry.SOnuPersistentData.PersMibAuditInterval = onuDeviceEntry.mibAuditInterval
277 onuDeviceEntry.alarmAuditInterval = dh.GetAlarmAuditInterval()
278 onuDeviceEntry.SOnuPersistentData.PersAlarmAuditInterval = onuDeviceEntry.alarmAuditInterval
279 } else {
280 logger.Debugw(ctx, "reconciling - take audit interval from persistent data", log.Fields{"device-id": onuDeviceEntry.deviceID})
281 // TODO: This is a preparation for VOL-VOL-3811 to preserve config history in case of
282 // vendor- or deviceID-specific configurations via voltctl-commands
283 onuDeviceEntry.mibAuditInterval = onuDeviceEntry.SOnuPersistentData.PersMibAuditInterval
284 onuDeviceEntry.alarmAuditInterval = onuDeviceEntry.SOnuPersistentData.PersAlarmAuditInterval
285 }
286 logger.Debugw(ctx, "MibAuditInterval and AlarmAuditInterval is set to", log.Fields{"mib-audit-interval": onuDeviceEntry.mibAuditInterval,
287 "alarm-audit-interval": onuDeviceEntry.alarmAuditInterval})
288 // TODO: periodical mib resync will be implemented with story VOL-3792
289 //onuDeviceEntry.mibNextDbResync = 0
290
291 // Omci related Mib upload sync state machine
292 mibUploadChan := make(chan cmn.Message, 2048)
293 onuDeviceEntry.PMibUploadFsm = cmn.NewAdapterFsm("MibUpload", onuDeviceEntry.deviceID, mibUploadChan)
294 onuDeviceEntry.PMibUploadFsm.PFsm = fsm.NewFSM(
295 UlStDisabled,
296 fsm.Events{
297
298 {Name: UlEvStart, Src: []string{UlStDisabled}, Dst: UlStStarting},
299
300 {Name: UlEvResetMib, Src: []string{UlStStarting}, Dst: UlStResettingMib},
301 {Name: UlEvGetVendorAndSerial, Src: []string{UlStResettingMib}, Dst: UlStGettingVendorAndSerial},
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +0000302 {Name: UlEvGetVersion, Src: []string{UlStGettingVendorAndSerial}, Dst: UlStGettingVersion},
303 {Name: UlEvGetEquipIDAndOmcc, Src: []string{UlStGettingVersion}, Dst: UlStGettingEquipIDAndOmcc},
Holger Hildebrandta6ef0e82022-04-06 13:11:32 +0000304 {Name: UlEvTestExtOmciSupport, Src: []string{UlStGettingEquipIDAndOmcc}, Dst: UlStTestingExtOmciSupport},
305 {Name: UlEvGetFirstSwVersion, Src: []string{UlStGettingEquipIDAndOmcc, UlStTestingExtOmciSupport}, Dst: UlStGettingFirstSwVersion},
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000306 {Name: UlEvGetSecondSwVersion, Src: []string{UlStGettingFirstSwVersion}, Dst: UlStGettingSecondSwVersion},
307 {Name: UlEvGetMacAddress, Src: []string{UlStGettingSecondSwVersion}, Dst: UlStGettingMacAddress},
308 {Name: UlEvGetMibTemplate, Src: []string{UlStGettingMacAddress}, Dst: UlStGettingMibTemplate},
309
310 {Name: UlEvUploadMib, Src: []string{UlStGettingMibTemplate}, Dst: UlStUploading},
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000311
312 {Name: UlEvVerifyAndStoreTPs, Src: []string{UlStStarting}, Dst: UlStVerifyingAndStoringTPs},
313 {Name: UlEvSuccess, Src: []string{UlStVerifyingAndStoringTPs}, Dst: UlStExaminingMds},
314 {Name: UlEvMismatch, Src: []string{UlStVerifyingAndStoringTPs}, Dst: UlStResettingMib},
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000315
316 {Name: UlEvSuccess, Src: []string{UlStGettingMibTemplate}, Dst: UlStUploadDone},
317 {Name: UlEvSuccess, Src: []string{UlStUploading}, Dst: UlStUploadDone},
318
319 {Name: UlEvSuccess, Src: []string{UlStUploadDone}, Dst: UlStInSync},
320 //{Name: UlEvSuccess, Src: []string{UlStExaminingMds}, Dst: UlStInSync},
321 {Name: UlEvSuccess, Src: []string{UlStExaminingMds}, Dst: UlStExaminingMdsSuccess},
322 // TODO: As long as mib-resynchronizing is not implemented, failed MDS-examination triggers
323 // mib-reset and new provisioning at this point
324 //{Name: UlEvMismatch, Src: []string{UlStExaminingMds}, Dst: UlStResynchronizing},
325 {Name: UlEvMismatch, Src: []string{UlStExaminingMds}, Dst: UlStResettingMib},
326
327 {Name: UlEvSuccess, Src: []string{UlStExaminingMdsSuccess}, Dst: UlStInSync},
328 {Name: UlEvMismatch, Src: []string{UlStExaminingMdsSuccess}, Dst: UlStResettingMib},
329
330 {Name: UlEvAuditMib, Src: []string{UlStInSync}, Dst: UlStAuditing},
331
332 {Name: UlEvSuccess, Src: []string{UlStOutOfSync}, Dst: UlStInSync},
333 {Name: UlEvAuditMib, Src: []string{UlStOutOfSync}, Dst: UlStAuditing},
334
335 {Name: UlEvSuccess, Src: []string{UlStAuditing}, Dst: UlStInSync},
336 {Name: UlEvMismatch, Src: []string{UlStAuditing}, Dst: UlStReAuditing},
337 {Name: UlEvForceResync, Src: []string{UlStAuditing}, Dst: UlStResynchronizing},
338
339 {Name: UlEvSuccess, Src: []string{UlStReAuditing}, Dst: UlStInSync},
340 {Name: UlEvMismatch, Src: []string{UlStReAuditing}, Dst: UlStResettingMib},
341
342 {Name: UlEvSuccess, Src: []string{UlStResynchronizing}, Dst: UlStInSync},
343 {Name: UlEvDiffsFound, Src: []string{UlStResynchronizing}, Dst: UlStOutOfSync},
344
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +0000345 {Name: UlEvTimeout, Src: []string{UlStResettingMib, UlStGettingVendorAndSerial, UlStGettingVersion, UlStGettingEquipIDAndOmcc, UlStTestingExtOmciSupport,
Holger Hildebrandta6ef0e82022-04-06 13:11:32 +0000346 UlStGettingFirstSwVersion, UlStGettingSecondSwVersion, UlStGettingMacAddress, UlStGettingMibTemplate, UlStUploading, UlStResynchronizing,
347 UlStVerifyingAndStoringTPs, UlStExaminingMds, UlStUploadDone, UlStInSync, UlStOutOfSync, UlStAuditing, UlStReAuditing}, Dst: UlStStarting},
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000348
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +0000349 {Name: UlEvStop, Src: []string{UlStStarting, UlStResettingMib, UlStGettingVendorAndSerial, UlStGettingVersion, UlStGettingEquipIDAndOmcc, UlStTestingExtOmciSupport,
Holger Hildebrandta6ef0e82022-04-06 13:11:32 +0000350 UlStGettingFirstSwVersion, UlStGettingSecondSwVersion, UlStGettingMacAddress, UlStGettingMibTemplate, UlStUploading, UlStResynchronizing,
351 UlStVerifyingAndStoringTPs, UlStExaminingMds, UlStUploadDone, UlStInSync, UlStOutOfSync, UlStAuditing, UlStReAuditing}, Dst: UlStDisabled},
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000352 },
353
354 fsm.Callbacks{
355 "enter_state": func(e *fsm.Event) { onuDeviceEntry.PMibUploadFsm.LogFsmStateChange(ctx, e) },
356 "enter_" + UlStStarting: func(e *fsm.Event) { onuDeviceEntry.enterStartingState(ctx, e) },
357 "enter_" + UlStResettingMib: func(e *fsm.Event) { onuDeviceEntry.enterResettingMibState(ctx, e) },
358 "enter_" + UlStGettingVendorAndSerial: func(e *fsm.Event) { onuDeviceEntry.enterGettingVendorAndSerialState(ctx, e) },
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +0000359 "enter_" + UlStGettingVersion: func(e *fsm.Event) { onuDeviceEntry.enterGettingVersionState(ctx, e) },
Holger Hildebrandta6ef0e82022-04-06 13:11:32 +0000360 "enter_" + UlStGettingEquipIDAndOmcc: func(e *fsm.Event) { onuDeviceEntry.enterGettingEquipIDAndOmccVersState(ctx, e) },
361 "enter_" + UlStTestingExtOmciSupport: func(e *fsm.Event) { onuDeviceEntry.enterTestingExtOmciSupportState(ctx, e) },
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000362 "enter_" + UlStGettingFirstSwVersion: func(e *fsm.Event) { onuDeviceEntry.enterGettingFirstSwVersionState(ctx, e) },
363 "enter_" + UlStGettingSecondSwVersion: func(e *fsm.Event) { onuDeviceEntry.enterGettingSecondSwVersionState(ctx, e) },
364 "enter_" + UlStGettingMacAddress: func(e *fsm.Event) { onuDeviceEntry.enterGettingMacAddressState(ctx, e) },
365 "enter_" + UlStGettingMibTemplate: func(e *fsm.Event) { onuDeviceEntry.enterGettingMibTemplateState(ctx, e) },
366 "enter_" + UlStUploading: func(e *fsm.Event) { onuDeviceEntry.enterUploadingState(ctx, e) },
367 "enter_" + UlStUploadDone: func(e *fsm.Event) { onuDeviceEntry.enterUploadDoneState(ctx, e) },
368 "enter_" + UlStExaminingMds: func(e *fsm.Event) { onuDeviceEntry.enterExaminingMdsState(ctx, e) },
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000369 "enter_" + UlStVerifyingAndStoringTPs: func(e *fsm.Event) { onuDeviceEntry.enterVerifyingAndStoringTPsState(ctx, e) },
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000370 "enter_" + UlStResynchronizing: func(e *fsm.Event) { onuDeviceEntry.enterResynchronizingState(ctx, e) },
371 "enter_" + UlStExaminingMdsSuccess: func(e *fsm.Event) { onuDeviceEntry.enterExaminingMdsSuccessState(ctx, e) },
372 "enter_" + UlStAuditing: func(e *fsm.Event) { onuDeviceEntry.enterAuditingState(ctx, e) },
373 "enter_" + UlStReAuditing: func(e *fsm.Event) { onuDeviceEntry.enterReAuditingState(ctx, e) },
374 "enter_" + UlStOutOfSync: func(e *fsm.Event) { onuDeviceEntry.enterOutOfSyncState(ctx, e) },
375 "enter_" + UlStInSync: func(e *fsm.Event) { onuDeviceEntry.enterInSyncState(ctx, e) },
376 },
377 )
378 // Omci related Mib download state machine
379 mibDownloadChan := make(chan cmn.Message, 2048)
380 onuDeviceEntry.PMibDownloadFsm = cmn.NewAdapterFsm("MibDownload", onuDeviceEntry.deviceID, mibDownloadChan)
381 onuDeviceEntry.PMibDownloadFsm.PFsm = fsm.NewFSM(
382 DlStDisabled,
383 fsm.Events{
384
385 {Name: DlEvStart, Src: []string{DlStDisabled}, Dst: DlStStarting},
386
387 {Name: DlEvCreateGal, Src: []string{DlStStarting}, Dst: DlStCreatingGal},
388 {Name: DlEvRxGalResp, Src: []string{DlStCreatingGal}, Dst: DlStSettingOnu2g},
389 {Name: DlEvRxOnu2gResp, Src: []string{DlStSettingOnu2g}, Dst: DlStBridgeInit},
390 // the bridge state is used for multi ME config for alle UNI related ports
391 // maybe such could be reflected in the state machine as well (port number parametrized)
392 // but that looks not straightforward here - so we keep it simple here for the beginning(?)
393 {Name: DlEvRxBridgeResp, Src: []string{DlStBridgeInit}, Dst: DlStDownloaded},
394
395 {Name: DlEvTimeoutSimple, Src: []string{DlStCreatingGal, DlStSettingOnu2g}, Dst: DlStStarting},
396 {Name: DlEvTimeoutBridge, Src: []string{DlStBridgeInit}, Dst: DlStStarting},
397
398 {Name: DlEvReset, Src: []string{DlStStarting, DlStCreatingGal, DlStSettingOnu2g,
399 DlStBridgeInit, DlStDownloaded}, Dst: DlStResetting},
400 // exceptional treatment for all states except DlStResetting
401 {Name: DlEvRestart, Src: []string{DlStStarting, DlStCreatingGal, DlStSettingOnu2g,
402 DlStBridgeInit, DlStDownloaded, DlStResetting}, Dst: DlStDisabled},
403 },
404
405 fsm.Callbacks{
406 "enter_state": func(e *fsm.Event) { onuDeviceEntry.PMibDownloadFsm.LogFsmStateChange(ctx, e) },
407 "enter_" + DlStStarting: func(e *fsm.Event) { onuDeviceEntry.enterDLStartingState(ctx, e) },
408 "enter_" + DlStCreatingGal: func(e *fsm.Event) { onuDeviceEntry.enterCreatingGalState(ctx, e) },
409 "enter_" + DlStSettingOnu2g: func(e *fsm.Event) { onuDeviceEntry.enterSettingOnu2gState(ctx, e) },
410 "enter_" + DlStBridgeInit: func(e *fsm.Event) { onuDeviceEntry.enterBridgeInitState(ctx, e) },
411 "enter_" + DlStDownloaded: func(e *fsm.Event) { onuDeviceEntry.enterDownloadedState(ctx, e) },
412 "enter_" + DlStResetting: func(e *fsm.Event) { onuDeviceEntry.enterResettingState(ctx, e) },
413 },
414 )
415 if onuDeviceEntry.PMibDownloadFsm == nil || onuDeviceEntry.PMibDownloadFsm.PFsm == nil {
416 logger.Errorw(ctx, "MibDownloadFsm could not be instantiated", log.Fields{"device-id": onuDeviceEntry.deviceID})
417 // TODO some specific error treatment - or waiting for crash ?
418 }
419
420 onuDeviceEntry.mibTemplateKVStore = onuDeviceEntry.baseDeviceHandler.SetBackend(ctx, cBasePathMibTemplateKvStore)
421 if onuDeviceEntry.mibTemplateKVStore == nil {
422 logger.Errorw(ctx, "Can't access mibTemplateKVStore - no backend connection to service",
423 log.Fields{"device-id": onuDeviceEntry.deviceID, "service": cBasePathMibTemplateKvStore})
424 }
425
426 onuDeviceEntry.onuKVStorePath = onuDeviceEntry.deviceID
Holger Hildebrandt60652202021-11-02 11:09:36 +0000427 baseKvStorePath := fmt.Sprintf(cmn.CBasePathOnuKVStore, dh.GetBackendPathPrefix())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000428 onuDeviceEntry.onuKVStore = onuDeviceEntry.baseDeviceHandler.SetBackend(ctx, baseKvStorePath)
429 if onuDeviceEntry.onuKVStore == nil {
430 logger.Errorw(ctx, "Can't access onuKVStore - no backend connection to service",
431 log.Fields{"device-id": onuDeviceEntry.deviceID, "service": baseKvStorePath})
432 }
433
434 // Alarm Synchronization Database
435
436 //self._alarm_db = None
437 //self._alarm_database_cls = support_classes['alarm-synchronizer']['database']
438 return &onuDeviceEntry
439}
440
nikesh.krishnan1249be92023-11-27 04:20:12 +0530441// Start starts (logs) the omci agent
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000442func (oo *OnuDeviceEntry) Start(ctx context.Context) error {
443 logger.Debugw(ctx, "OnuDeviceEntry-starting", log.Fields{"for device-id": oo.deviceID})
444 if oo.PDevOmciCC == nil {
445 oo.PDevOmciCC = cmn.NewOmciCC(ctx, oo.deviceID, oo.baseDeviceHandler, oo, oo.baseDeviceHandler.GetOnuAlarmManager(), oo.coreClient)
446 if oo.PDevOmciCC == nil {
447 logger.Errorw(ctx, "Could not create devOmciCc - abort", log.Fields{"for device-id": oo.deviceID})
448 return fmt.Errorf("could not create devOmciCc %s", oo.deviceID)
449 }
450 }
451 return nil
452}
453
nikesh.krishnan1249be92023-11-27 04:20:12 +0530454// Stop stops/resets the omciCC
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000455func (oo *OnuDeviceEntry) Stop(ctx context.Context, abResetOmciCC bool) error {
456 logger.Debugw(ctx, "OnuDeviceEntry-stopping", log.Fields{"for device-id": oo.deviceID})
457 if abResetOmciCC && (oo.PDevOmciCC != nil) {
458 _ = oo.PDevOmciCC.Stop(ctx)
459 }
460 //to allow for all event notifications again when re-using the device and omciCC
461 oo.devState = cmn.DeviceStatusInit
462 return nil
463}
464
465// Reboot - TODO: add comment
466func (oo *OnuDeviceEntry) Reboot(ctx context.Context) error {
467 logger.Debugw(ctx, "OnuDeviceEntry-rebooting", log.Fields{"for device-id": oo.deviceID})
468 if oo.PDevOmciCC != nil {
469 if err := oo.PDevOmciCC.SendReboot(ctx, oo.baseDeviceHandler.GetOmciTimeout(), true, oo.omciRebootMessageReceivedChannel); err != nil {
470 logger.Errorw(ctx, "onu didn't reboot", log.Fields{"for device-id": oo.deviceID})
471 return err
472 }
473 }
474 return nil
475}
476
477// WaitForRebootResponse - TODO: add comment
478func (oo *OnuDeviceEntry) WaitForRebootResponse(ctx context.Context, responseChannel chan cmn.Message) error {
479 select {
480 case <-time.After(oo.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
481 logger.Warnw(ctx, "reboot timeout", log.Fields{"for device-id": oo.deviceID})
482 return fmt.Errorf("rebootTimeout")
483 case data := <-responseChannel:
484 switch data.Data.(cmn.OmciMessage).OmciMsg.MessageType {
485 case omci.RebootResponseType:
486 {
487 msgLayer := (*data.Data.(cmn.OmciMessage).OmciPacket).Layer(omci.LayerTypeRebootResponse)
488 if msgLayer == nil {
489 return fmt.Errorf("omci Msg layer could not be detected for RebootResponseType")
490 }
491 msgObj, msgOk := msgLayer.(*omci.RebootResponse)
492 if !msgOk {
493 return fmt.Errorf("omci Msg layer could not be assigned for RebootResponseType %s", oo.deviceID)
494 }
495 logger.Debugw(ctx, "RebootResponse data", log.Fields{"device-id": oo.deviceID, "data-fields": msgObj})
496 if msgObj.Result != me.Success {
497 logger.Errorw(ctx, "Omci RebootResponse result error", log.Fields{"device-id": oo.deviceID, "Error": msgObj.Result})
498 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
499 return fmt.Errorf("omci RebootResponse result error indication %s for device %s",
500 msgObj.Result, oo.deviceID)
501 }
502 return nil
503 }
504 }
505 logger.Warnw(ctx, "Reboot response message type error", log.Fields{"for device-id": oo.deviceID})
506 return fmt.Errorf("unexpected OmciResponse type received %s", oo.deviceID)
507 }
508}
509
nikesh.krishnan1249be92023-11-27 04:20:12 +0530510// Relay the InSync message via Handler to Rw core - Status update
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000511func (oo *OnuDeviceEntry) transferSystemEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000512 logger.Debugw(ctx, "relaying system-event", log.Fields{"device-id": oo.deviceID, "Event": devEvent})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000513 // decouple the handler transfer from further processing here
514 // TODO!!! check if really no synch is required within the system e.g. to ensure following steps ..
515 if devEvent == cmn.MibDatabaseSync {
516 if oo.devState < cmn.MibDatabaseSync { //devState has not been synced yet
517 oo.devState = cmn.MibDatabaseSync
518 go oo.baseDeviceHandler.DeviceProcStatusUpdate(ctx, devEvent)
519 //TODO!!! device control: next step: start MIB capability verification from here ?!!!
520 } else {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000521 logger.Debugw(ctx, "mibinsync-event in some already synced state - ignored",
522 log.Fields{"device-id": oo.deviceID, "state": oo.devState})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000523 }
524 } else if devEvent == cmn.MibDownloadDone {
525 if oo.devState < cmn.MibDownloadDone { //devState has not been synced yet
526 oo.devState = cmn.MibDownloadDone
527 go oo.baseDeviceHandler.DeviceProcStatusUpdate(ctx, devEvent)
528 } else {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000529 logger.Debugw(ctx, "mibdownloaddone-event was already seen - ignored",
530 log.Fields{"device-id": oo.deviceID, "state": oo.devState})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000531 }
532 } else {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000533 logger.Warnw(ctx, "device-event not yet handled",
534 log.Fields{"device-id": oo.deviceID, "state": devEvent})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000535 }
536}
537
538// RestoreDataFromOnuKvStore - TODO: add comment
539func (oo *OnuDeviceEntry) RestoreDataFromOnuKvStore(ctx context.Context) error {
540 if oo.onuKVStore == nil {
541 logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
542 return fmt.Errorf(fmt.Sprintf("onuKVStore-not-set-abort-%s", oo.deviceID))
543 }
544 oo.MutexPersOnuConfig.Lock()
545 defer oo.MutexPersOnuConfig.Unlock()
546 oo.SOnuPersistentData =
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +0000547 onuPersistentData{0, 0, "", "", "", "", "", false, "", "", "", false, false, oo.mibAuditInterval, 0, 0,
548 make([]uniPersConfig, 0), oo.alarmAuditInterval, make(map[uint16]uint16)}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000549 oo.mutexOnuKVStore.RLock()
550 Value, err := oo.onuKVStore.Get(ctx, oo.onuKVStorePath)
551 oo.mutexOnuKVStore.RUnlock()
552 if err == nil {
553 if Value != nil {
554 logger.Debugw(ctx, "ONU-data read",
555 log.Fields{"Key": Value.Key, "device-id": oo.deviceID})
556 tmpBytes, _ := kvstore.ToByte(Value.Value)
557
558 if err = json.Unmarshal(tmpBytes, &oo.SOnuPersistentData); err != nil {
559 logger.Errorw(ctx, "unable to unmarshal ONU-data", log.Fields{"error": err, "device-id": oo.deviceID})
560 return fmt.Errorf(fmt.Sprintf("unable-to-unmarshal-ONU-data-%s", oo.deviceID))
561 }
562 logger.Debugw(ctx, "ONU-data", log.Fields{"SOnuPersistentData": oo.SOnuPersistentData,
563 "device-id": oo.deviceID})
564 } else {
565 logger.Debugw(ctx, "no ONU-data found", log.Fields{"path": oo.onuKVStorePath, "device-id": oo.deviceID})
566 return fmt.Errorf("no-ONU-data-found")
567 }
568 } else {
569 logger.Errorw(ctx, "unable to read from KVstore", log.Fields{"device-id": oo.deviceID})
570 return fmt.Errorf(fmt.Sprintf("unable-to-read-from-KVstore-%s", oo.deviceID))
571 }
572 return nil
573}
574
575// DeleteDataFromOnuKvStore - TODO: add comment
576func (oo *OnuDeviceEntry) DeleteDataFromOnuKvStore(ctx context.Context, wg *sync.WaitGroup) {
577 defer wg.Done()
578
579 if oo.onuKVStore == nil {
580 logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
581 oo.setKvProcessingErrorIndication(errors.New("onu-data delete aborted: onuKVStore not set"))
582 return
583 }
584 var processingStep uint8 = 1 // used to synchronize the different processing steps with chOnuKvProcessingStep
585 go oo.deletePersistentData(ctx, processingStep)
586 if !oo.waitForTimeoutOrCompletion(ctx, oo.chOnuKvProcessingStep, processingStep) {
587 //timeout or error detected
588 logger.Debugw(ctx, "ONU-data not deleted - abort", log.Fields{"device-id": oo.deviceID})
589 oo.setKvProcessingErrorIndication(errors.New("onu-data delete aborted: during kv-access"))
590 return
591 }
592}
593
594func (oo *OnuDeviceEntry) deletePersistentData(ctx context.Context, aProcessingStep uint8) {
595
596 logger.Debugw(ctx, "delete and clear internal persistency data", log.Fields{"device-id": oo.deviceID})
597
598 oo.MutexPersOnuConfig.Lock()
599 defer oo.MutexPersOnuConfig.Unlock()
600
601 oo.SOnuPersistentData.PersUniConfig = nil //releasing all UniConfig entries to garbage collector default entry
602 oo.SOnuPersistentData =
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +0000603 onuPersistentData{0, 0, "", "", "", "", "", false, "", "", "", false, false, oo.mibAuditInterval, 0, 0,
604 make([]uniPersConfig, 0), oo.alarmAuditInterval, make(map[uint16]uint16)}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000605 logger.Debugw(ctx, "delete ONU-data from KVStore", log.Fields{"device-id": oo.deviceID})
606 oo.mutexOnuKVStore.Lock()
607 err := oo.onuKVStore.Delete(ctx, oo.onuKVStorePath)
608 oo.mutexOnuKVStore.Unlock()
609 if err != nil {
610 logger.Errorw(ctx, "unable to delete in KVstore", log.Fields{"device-id": oo.deviceID, "err": err})
611 oo.chOnuKvProcessingStep <- 0 //error indication
612 return
613 }
614 oo.chOnuKvProcessingStep <- aProcessingStep //done
615}
616
617// UpdateOnuKvStore - TODO: add comment
618func (oo *OnuDeviceEntry) UpdateOnuKvStore(ctx context.Context, wg *sync.WaitGroup) {
619 defer wg.Done()
620
621 if oo.onuKVStore == nil {
622 logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
623 oo.setKvProcessingErrorIndication(errors.New("onu-data update aborted: onuKVStore not set"))
624 return
625 }
626 var processingStep uint8 = 1 // used to synchronize the different processing steps with chOnuKvProcessingStep
627 go oo.storeDataInOnuKvStore(ctx, processingStep)
628 if !oo.waitForTimeoutOrCompletion(ctx, oo.chOnuKvProcessingStep, processingStep) {
629 //timeout or error detected
630 logger.Debugw(ctx, "ONU-data not written - abort", log.Fields{"device-id": oo.deviceID})
631 oo.setKvProcessingErrorIndication(errors.New("onu-data update aborted: during writing process"))
632 return
633 }
634}
635
636func (oo *OnuDeviceEntry) storeDataInOnuKvStore(ctx context.Context, aProcessingStep uint8) {
637
638 oo.MutexPersOnuConfig.Lock()
639 defer oo.MutexPersOnuConfig.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000640
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000641 oo.pOpenOnuAc.RLockMutexDeviceHandlersMap()
642 if _, exist := oo.pOpenOnuAc.GetDeviceHandler(oo.deviceID); !exist {
643 logger.Debugw(ctx, "delete_device in progress - skip write request", log.Fields{"device-id": oo.deviceID})
644 oo.chOnuKvProcessingStep <- aProcessingStep
645 oo.pOpenOnuAc.RUnlockMutexDeviceHandlersMap()
646 return
647 }
648 oo.baseDeviceHandler.RLockMutexDeletionInProgressFlag()
649 if oo.baseDeviceHandler.GetDeletionInProgress() {
650 logger.Debugw(ctx, "delete_device in progress - skip write request", log.Fields{"device-id": oo.deviceID})
651 oo.chOnuKvProcessingStep <- aProcessingStep
652 oo.pOpenOnuAc.RUnlockMutexDeviceHandlersMap()
653 oo.baseDeviceHandler.RUnlockMutexDeletionInProgressFlag()
654 return
655 }
656 oo.pOpenOnuAc.RUnlockMutexDeviceHandlersMap()
657 oo.baseDeviceHandler.RUnlockMutexDeletionInProgressFlag()
658
nikesh.krishnan1249be92023-11-27 04:20:12 +0530659 //assign values which are not already present when NewOnuDeviceEntry() is called
660 onuIndication := oo.baseDeviceHandler.GetOnuIndication()
661 if onuIndication != nil {
662 oo.SOnuPersistentData.PersOnuID = onuIndication.OnuId
663 oo.SOnuPersistentData.PersIntfID = onuIndication.IntfId
664 //TODO: verify usage of these values during restart UC
665 oo.SOnuPersistentData.PersAdminState = onuIndication.AdminState
666 oo.SOnuPersistentData.PersOperState = onuIndication.OperState
667 } else {
668 logger.Errorw(ctx, "onuIndication not set, unable to load ONU-data", log.Fields{"device-id": oo.deviceID})
669 oo.chOnuKvProcessingStep <- 0 //error indication
670 return
671 }
672
673 logger.Debugw(ctx, "Update ONU-data in KVStore", log.Fields{"device-id": oo.deviceID, "SOnuPersistentData": oo.SOnuPersistentData})
674
675 Value, err := json.Marshal(oo.SOnuPersistentData)
676 if err != nil {
677 logger.Errorw(ctx, "unable to marshal ONU-data", log.Fields{"SOnuPersistentData": oo.SOnuPersistentData,
678 "device-id": oo.deviceID, "err": err})
679 oo.chOnuKvProcessingStep <- 0 //error indication
680 return
681 }
682
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000683 oo.mutexOnuKVStore.Lock()
684 err = oo.onuKVStore.Put(ctx, oo.onuKVStorePath, Value)
685 oo.mutexOnuKVStore.Unlock()
686 if err != nil {
687 logger.Errorw(ctx, "unable to write ONU-data into KVstore", log.Fields{"device-id": oo.deviceID, "err": err})
688 oo.chOnuKvProcessingStep <- 0 //error indication
689 return
690 }
691 oo.chOnuKvProcessingStep <- aProcessingStep //done
692}
693
694// UpdateOnuUniTpPath - TODO: add comment
695func (oo *OnuDeviceEntry) UpdateOnuUniTpPath(ctx context.Context, aUniID uint8, aTpID uint8, aPathString string) bool {
696 /* within some specific InterAdapter processing request write/read access to data is ensured to be sequentially,
697 as also the complete sequence is ensured to 'run to completion' before some new request is accepted
698 no specific concurrency protection to SOnuPersistentData is required here
699 */
700 oo.MutexPersOnuConfig.Lock()
701 defer oo.MutexPersOnuConfig.Unlock()
702
703 for k, v := range oo.SOnuPersistentData.PersUniConfig {
704 if v.PersUniID == aUniID {
705 existingPath, ok := oo.SOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID]
706 logger.Debugw(ctx, "PersUniConfig-entry exists", log.Fields{"device-id": oo.deviceID, "uniID": aUniID,
707 "tpID": aTpID, "path": aPathString, "existingPath": existingPath, "ok": ok})
708 if !ok {
709 logger.Debugw(ctx, "tp-does-not-exist", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "tpID": aTpID, "path": aPathString})
710 }
711 if existingPath != aPathString {
712 if aPathString == "" {
713 //existing entry to be deleted
714 logger.Debugw(ctx, "UniTp delete path value", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
715 oo.SOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID] = ""
716 } else {
717 //existing entry to be modified
718 logger.Debugw(ctx, "UniTp modify path value", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
719 oo.SOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID] = aPathString
720 }
721 return true
722 }
723 //entry already exists
724 if aPathString == "" {
725 //no active TechProfile
726 logger.Debugw(ctx, "UniTp path has already been removed - no AniSide config to be removed", log.Fields{
727 "device-id": oo.deviceID, "uniID": aUniID})
728 } else {
729 //the given TechProfile already exists and is assumed to be active - update devReason as if the config has been done here
730 //was needed e.g. in voltha POD Tests:Validate authentication on a disabled ONU
731 // (as here the TechProfile has not been removed with the disable-device before the new enable-device)
732 logger.Debugw(ctx, "UniTp path already exists - TechProfile supposed to be active", log.Fields{
733 "device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
734 //no deviceReason update (DeviceProcStatusUpdate) here to ensure 'omci_flows_pushed' state within disable/enable procedure of ATT scenario
735 // (during which the flows are removed/re-assigned but the techProf is left active)
736 //and as the TechProfile is regarded as active we have to verify, if some flow configuration still waits on it
737 // (should not be the case, but should not harm or be more robust ...)
738 // and to be sure, that for some reason the corresponding TpDelete was lost somewhere in history
739 // we also reset a possibly outstanding delete request - repeated TpConfig is regarded as valid for waiting flow config
740 if oo.pOnuTP != nil {
741 oo.pOnuTP.SetProfileToDelete(aUniID, aTpID, false)
742 }
743 go oo.baseDeviceHandler.VerifyVlanConfigRequest(ctx, aUniID, aTpID)
744 }
745 return false //indicate 'no change' - nothing more to do, TechProf inter-adapter message is return with success anyway here
746 }
747 }
748 //no entry exists for uniId
749
750 if aPathString == "" {
751 //delete request in non-existing state , accept as no change
752 logger.Debugw(ctx, "UniTp path already removed", log.Fields{"device-id": oo.deviceID, "uniID": aUniID})
753 return false
754 }
755 //new entry to be created
756 logger.Debugw(ctx, "New UniTp path set", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
757 perSubTpPathMap := make(map[uint8]string)
758 perSubTpPathMap[aTpID] = aPathString
759 oo.SOnuPersistentData.PersUniConfig =
760 append(oo.SOnuPersistentData.PersUniConfig, uniPersConfig{PersUniID: aUniID, PersTpPathMap: perSubTpPathMap, PersFlowParams: make([]cmn.UniVlanFlowParams, 0)})
761 return true
762}
763
764// UpdateOnuUniFlowConfig - TODO: add comment
765func (oo *OnuDeviceEntry) UpdateOnuUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]cmn.UniVlanFlowParams) {
766
767 oo.MutexPersOnuConfig.Lock()
768 defer oo.MutexPersOnuConfig.Unlock()
769
770 for k, v := range oo.SOnuPersistentData.PersUniConfig {
771 if v.PersUniID == aUniID {
772 oo.SOnuPersistentData.PersUniConfig[k].PersFlowParams = make([]cmn.UniVlanFlowParams, len(*aUniVlanFlowParams))
773 copy(oo.SOnuPersistentData.PersUniConfig[k].PersFlowParams, *aUniVlanFlowParams)
774 return
775 }
776 }
777 //flow update was faster than tp-config - create PersUniConfig-entry
778 //TODO!!: following activity to 'add' some new uni entry might not be quite correct if this function is called to clear the data
779 // (e.g after flow removal from RemoveUniFlowParams()).
780 // This has the effect of misleading indication that there is still some active UNI entry, even though there might be only some nil flow entry
781 // The effect of this flaw is that at TechProfile removal there is an additional attempt to remove the entry even though no techProfile exists anymore
782 // The code is not changed here because of the current release lane, changes might have unexpected secondary effects, perhaps later with more elaborate tests
783 tmpConfig := uniPersConfig{PersUniID: aUniID, PersTpPathMap: make(map[uint8]string), PersFlowParams: make([]cmn.UniVlanFlowParams, len(*aUniVlanFlowParams))}
784 copy(tmpConfig.PersFlowParams, *aUniVlanFlowParams)
785 oo.SOnuPersistentData.PersUniConfig = append(oo.SOnuPersistentData.PersUniConfig, tmpConfig)
786}
787
788func (oo *OnuDeviceEntry) waitForTimeoutOrCompletion(
789 ctx context.Context, aChOnuProcessingStep <-chan uint8, aProcessingStep uint8) bool {
790 select {
791 case <-ctx.Done():
792 logger.Warnw(ctx, "processing not completed in-time!",
793 log.Fields{"device-id": oo.deviceID, "error": ctx.Err()})
794 return false
795 case rxStep := <-aChOnuProcessingStep:
796 if rxStep == aProcessingStep {
797 return true
798 }
799 //all other values are not accepted - including 0 for error indication
800 logger.Warnw(ctx, "Invalid processing step received: abort!",
801 log.Fields{"device-id": oo.deviceID,
802 "wantedStep": aProcessingStep, "haveStep": rxStep})
803 return false
804 }
805}
806
807// ResetKvProcessingErrorIndication - TODO: add comment
808func (oo *OnuDeviceEntry) ResetKvProcessingErrorIndication() {
809 oo.mutexOnuKVStoreProcResult.Lock()
810 oo.onuKVStoreProcResult = nil
811 oo.mutexOnuKVStoreProcResult.Unlock()
812}
813
814// GetKvProcessingErrorIndication - TODO: add comment
815func (oo *OnuDeviceEntry) GetKvProcessingErrorIndication() error {
816 oo.mutexOnuKVStoreProcResult.RLock()
817 value := oo.onuKVStoreProcResult
818 oo.mutexOnuKVStoreProcResult.RUnlock()
819 return value
820}
821
822func (oo *OnuDeviceEntry) setKvProcessingErrorIndication(value error) {
823 oo.mutexOnuKVStoreProcResult.Lock()
824 oo.onuKVStoreProcResult = value
825 oo.mutexOnuKVStoreProcResult.Unlock()
826}
827
828// IncrementMibDataSync - TODO: add comment
829func (oo *OnuDeviceEntry) IncrementMibDataSync(ctx context.Context) {
830 oo.MutexPersOnuConfig.Lock()
831 defer oo.MutexPersOnuConfig.Unlock()
832 if oo.SOnuPersistentData.PersMibDataSyncAdpt < 255 {
833 oo.SOnuPersistentData.PersMibDataSyncAdpt++
834 } else {
835 // per G.984 and G.988 overflow starts over at 1 given 0 is reserved for reset
836 oo.SOnuPersistentData.PersMibDataSyncAdpt = 1
837 }
838 logger.Debugf(ctx, "mibDataSync updated - mds: %d - device-id: %s", oo.SOnuPersistentData.PersMibDataSyncAdpt, oo.deviceID)
839}
840
841// ModifySwImageInactiveVersion - updates the inactive SW image version stored
842func (oo *OnuDeviceEntry) ModifySwImageInactiveVersion(ctx context.Context, aImageVersion string) {
843 oo.mutexOnuSwImageIndications.Lock()
844 defer oo.mutexOnuSwImageIndications.Unlock()
845 logger.Debugw(ctx, "software-image set inactive version", log.Fields{
846 "device-id": oo.deviceID, "version": aImageVersion})
847 oo.onuSwImageIndications.InActiveEntityEntry.Version = aImageVersion
848 //inactive SW version is not part of persistency data (yet) - no need to update that
849}
850
851// ModifySwImageActiveCommit - updates the active SW commit flag stored
852func (oo *OnuDeviceEntry) ModifySwImageActiveCommit(ctx context.Context, aCommitted uint8) {
853 oo.mutexOnuSwImageIndications.Lock()
854 defer oo.mutexOnuSwImageIndications.Unlock()
855 logger.Debugw(ctx, "software-image set active entity commit flag", log.Fields{
856 "device-id": oo.deviceID, "committed": aCommitted})
857 oo.onuSwImageIndications.ActiveEntityEntry.IsCommitted = aCommitted
858 //commit flag is not part of persistency data (yet) - no need to update that
859}
860
861// GetActiveImageVersion - returns the active SW image version stored
862func (oo *OnuDeviceEntry) GetActiveImageVersion(ctx context.Context) string {
863 oo.mutexOnuSwImageIndications.RLock()
864 if oo.onuSwImageIndications.ActiveEntityEntry.Valid {
865 value := oo.onuSwImageIndications.ActiveEntityEntry.Version
866 oo.mutexOnuSwImageIndications.RUnlock()
867 return value
868 }
869 oo.mutexOnuSwImageIndications.RUnlock()
870 logger.Debugw(ctx, "Active Image is not valid", log.Fields{"device-id": oo.deviceID})
871 return ""
872}
873
874// GetInactiveImageVersion - TODO: add comment
875func (oo *OnuDeviceEntry) GetInactiveImageVersion(ctx context.Context) string {
876 oo.mutexOnuSwImageIndications.RLock()
877 if oo.onuSwImageIndications.InActiveEntityEntry.Valid {
878 value := oo.onuSwImageIndications.InActiveEntityEntry.Version
879 oo.mutexOnuSwImageIndications.RUnlock()
880 return value
881 }
882 oo.mutexOnuSwImageIndications.RUnlock()
883 logger.Debugw(ctx, "Inactive Image is not valid", log.Fields{"device-id": oo.deviceID})
884 return ""
885}
886
887func (oo *OnuDeviceEntry) buildMibTemplatePath() string {
888 oo.MutexPersOnuConfig.RLock()
889 defer oo.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt6a001d02022-06-15 08:32:48 +0000890 return fmt.Sprintf(cSuffixMibTemplateKvStore, oo.SOnuPersistentData.PersVendorID, oo.SOnuPersistentData.PersVersion,
891 oo.SOnuPersistentData.PersActiveSwVersion)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000892}
893
894// AllocateFreeTcont - TODO: add comment
895func (oo *OnuDeviceEntry) AllocateFreeTcont(ctx context.Context, allocID uint16) (uint16, bool, error) {
896 logger.Debugw(ctx, "allocate-free-tcont", log.Fields{"device-id": oo.deviceID, "allocID": allocID,
897 "allocated-instances": oo.SOnuPersistentData.PersTcontMap})
898
mpagenko2c3f6c52021-11-23 11:22:10 +0000899 oo.MutexPersOnuConfig.Lock()
900 defer oo.MutexPersOnuConfig.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000901 if entityID, ok := oo.SOnuPersistentData.PersTcontMap[allocID]; ok {
902 //tcont already allocated before, return the used instance-id
903 return entityID, true, nil
904 }
905 //First allocation of tcont. Find a free instance
906 if tcontInstKeys := oo.pOnuDB.GetSortedInstKeys(ctx, me.TContClassID); len(tcontInstKeys) > 0 {
907 logger.Debugw(ctx, "allocate-free-tcont-db-keys", log.Fields{"device-id": oo.deviceID, "keys": tcontInstKeys})
908 for _, instID := range tcontInstKeys {
909 instExist := false
910 //If this instance exist in map, it means it is not empty. It is allocated before
911 for _, v := range oo.SOnuPersistentData.PersTcontMap {
912 if v == instID {
913 instExist = true
914 break
915 }
916 }
917 if !instExist {
918 oo.SOnuPersistentData.PersTcontMap[allocID] = instID
919 return instID, false, nil
920 }
921 }
922 }
923 return 0, false, fmt.Errorf(fmt.Sprintf("no-free-tcont-left-for-device-%s", oo.deviceID))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000924}
925
926// FreeTcont - TODO: add comment
927func (oo *OnuDeviceEntry) FreeTcont(ctx context.Context, allocID uint16) {
928 logger.Debugw(ctx, "free-tcont", log.Fields{"device-id": oo.deviceID, "alloc": allocID})
mpagenko2c3f6c52021-11-23 11:22:10 +0000929 oo.MutexPersOnuConfig.Lock()
930 defer oo.MutexPersOnuConfig.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000931 delete(oo.SOnuPersistentData.PersTcontMap, allocID)
932}
933
934// GetDevOmciCC - TODO: add comment
935func (oo *OnuDeviceEntry) GetDevOmciCC() *cmn.OmciCC {
936 return oo.PDevOmciCC
937}
938
939// GetOnuDB - TODO: add comment
940func (oo *OnuDeviceEntry) GetOnuDB() *devdb.OnuDeviceDB {
941 return oo.pOnuDB
942}
943
944// GetPersSerialNumber - TODO: add comment
945func (oo *OnuDeviceEntry) GetPersSerialNumber() string {
mpagenko2c3f6c52021-11-23 11:22:10 +0000946 oo.MutexPersOnuConfig.RLock()
947 defer oo.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000948 value := oo.SOnuPersistentData.PersSerialNumber
949 return value
950}
951
952// GetPersVendorID - TODO: add comment
953func (oo *OnuDeviceEntry) GetPersVendorID() string {
mpagenko2c3f6c52021-11-23 11:22:10 +0000954 oo.MutexPersOnuConfig.RLock()
955 defer oo.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000956 value := oo.SOnuPersistentData.PersVendorID
957 return value
958}
959
Holger Hildebrandt0edf5b02022-05-04 14:19:43 +0000960// GetPersIsExtOmciSupported - TODO: add comment
961func (oo *OnuDeviceEntry) GetPersIsExtOmciSupported() bool {
962 oo.MutexPersOnuConfig.RLock()
963 defer oo.MutexPersOnuConfig.RUnlock()
964 value := oo.SOnuPersistentData.PersIsExtOmciSupported
965 return value
966}
967
Holger Hildebrandt6a001d02022-06-15 08:32:48 +0000968// GetPersVersion - TODO: add comment
969func (oo *OnuDeviceEntry) GetPersVersion() string {
970 oo.MutexPersOnuConfig.RLock()
971 defer oo.MutexPersOnuConfig.RUnlock()
972 value := oo.SOnuPersistentData.PersVersion
973 return value
974}
975
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000976// GetPersEquipmentID - TODO: add comment
977func (oo *OnuDeviceEntry) GetPersEquipmentID() string {
mpagenko2c3f6c52021-11-23 11:22:10 +0000978 oo.MutexPersOnuConfig.RLock()
979 defer oo.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000980 value := oo.SOnuPersistentData.PersEquipmentID
981 return value
982}
983
984// GetMibUploadFsmCommChan - TODO: add comment
985func (oo *OnuDeviceEntry) GetMibUploadFsmCommChan() chan cmn.Message {
986 return oo.PMibUploadFsm.CommChan
987}
988
989// GetMibDownloadFsmCommChan - TODO: add comment
990func (oo *OnuDeviceEntry) GetMibDownloadFsmCommChan() chan cmn.Message {
991 return oo.PMibDownloadFsm.CommChan
992}
993
994// GetOmciRebootMsgRevChan - TODO: add comment
995func (oo *OnuDeviceEntry) GetOmciRebootMsgRevChan() chan cmn.Message {
996 return oo.omciRebootMessageReceivedChannel
997}
998
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000999// GetPersActiveSwVersion - TODO: add comment
1000func (oo *OnuDeviceEntry) GetPersActiveSwVersion() string {
mpagenko2c3f6c52021-11-23 11:22:10 +00001001 oo.MutexPersOnuConfig.RLock()
1002 defer oo.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001003 return oo.SOnuPersistentData.PersActiveSwVersion
1004}
1005
1006// SetPersActiveSwVersion - TODO: add comment
1007func (oo *OnuDeviceEntry) SetPersActiveSwVersion(value string) {
mpagenko2c3f6c52021-11-23 11:22:10 +00001008 oo.MutexPersOnuConfig.Lock()
1009 defer oo.MutexPersOnuConfig.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001010 oo.SOnuPersistentData.PersActiveSwVersion = value
1011}
1012
mpagenko101ac942021-11-16 15:01:29 +00001013// setReconcilingFlows - TODO: add comment
1014func (oo *OnuDeviceEntry) setReconcilingFlows(value bool) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001015 oo.mutexReconcilingFlowsFlag.Lock()
1016 oo.reconcilingFlows = value
1017 oo.mutexReconcilingFlowsFlag.Unlock()
1018}
1019
mpagenko101ac942021-11-16 15:01:29 +00001020// SendChReconcilingFlowsFinished - TODO: add comment
Holger Hildebrandtf2fcdd42021-12-15 11:42:19 +00001021func (oo *OnuDeviceEntry) SendChReconcilingFlowsFinished(ctx context.Context, value bool) {
mpagenko101ac942021-11-16 15:01:29 +00001022 if oo != nil { //if the object still exists (might have been already deleted in background)
1023 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1024 select {
1025 case oo.chReconcilingFlowsFinished <- value:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301026 logger.Info(ctx, "reconciling - flows finished sent", log.Fields{"device-id": oo.deviceID})
mpagenko101ac942021-11-16 15:01:29 +00001027 default:
Holger Hildebrandtf2fcdd42021-12-15 11:42:19 +00001028 logger.Infow(ctx, "reconciling - flows finished not sent!", log.Fields{"device-id": oo.deviceID})
mpagenko101ac942021-11-16 15:01:29 +00001029 }
1030 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001031}
1032
mpagenko101ac942021-11-16 15:01:29 +00001033// isReconcilingFlows - TODO: add comment
1034func (oo *OnuDeviceEntry) isReconcilingFlows() bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001035 oo.mutexReconcilingFlowsFlag.RLock()
1036 value := oo.reconcilingFlows
1037 oo.mutexReconcilingFlowsFlag.RUnlock()
1038 return value
1039}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00001040
1041// PrepareForGarbageCollection - remove references to prepare for garbage collection
1042func (oo *OnuDeviceEntry) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
1043 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
1044 oo.baseDeviceHandler = nil
1045 oo.pOnuTP = nil
1046 if oo.PDevOmciCC != nil {
1047 oo.PDevOmciCC.PrepareForGarbageCollection(ctx, aDeviceID)
1048 }
1049 oo.PDevOmciCC = nil
1050}
Holger Hildebrandtc56febd2022-02-09 13:23:30 +00001051
nikesh.krishnan1249be92023-11-27 04:20:12 +05301052// SendOnuDeviceEvent sends an ONU DeviceEvent via eventProxy
Holger Hildebrandtc56febd2022-02-09 13:23:30 +00001053func (oo *OnuDeviceEntry) SendOnuDeviceEvent(ctx context.Context, aDeviceEventName string, aDescription string) {
1054
1055 oo.MutexPersOnuConfig.RLock()
1056 context := make(map[string]string)
1057 context["onu-id"] = strconv.FormatUint(uint64(oo.SOnuPersistentData.PersOnuID), 10)
1058 context["intf-id"] = strconv.FormatUint(uint64(oo.SOnuPersistentData.PersIntfID), 10)
1059 context["onu-serial-number"] = oo.SOnuPersistentData.PersSerialNumber
1060 oo.MutexPersOnuConfig.RUnlock()
1061
1062 deviceEvent := &voltha.DeviceEvent{
1063 ResourceId: oo.deviceID,
1064 DeviceEventName: aDeviceEventName,
1065 Description: aDescription,
1066 Context: context,
1067 }
Holger Hildebrandt7e138462023-03-29 12:12:14 +00001068 logger.Debugw(ctx, "send device event", log.Fields{"deviceEvent": deviceEvent, "device-id": oo.deviceID})
Holger Hildebrandtc56febd2022-02-09 13:23:30 +00001069 _ = oo.eventProxy.SendDeviceEvent(ctx, deviceEvent, voltha.EventCategory_COMMUNICATION, voltha.EventSubCategory_ONU, time.Now().Unix())
1070}