blob: 517a94a003eb0efb9c8339f1fdcc198b92f9750a [file] [log] [blame]
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
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
17//Package mib provides the utilities for managing the onu mib
18package mib
19
20import (
21 "context"
22 "encoding/json"
23 "errors"
24 "fmt"
25 "sync"
26 "time"
27
28 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000029 "github.com/opencord/omci-lib-go/v2"
30 me "github.com/opencord/omci-lib-go/v2/generated"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000031 "github.com/opencord/voltha-lib-go/v7/pkg/db"
32 "github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
33 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
34
35 "github.com/opencord/voltha-lib-go/v7/pkg/log"
36
37 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
38 devdb "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/devdb"
39 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/swupg"
40)
41
42// events of MibUpload FSM
43const (
44 UlEvStart = "UlEvStart"
45 UlEvResetMib = "UlEvResetMib"
46 UlEvGetVendorAndSerial = "UlEvGetVendorAndSerial"
47 UlEvGetEquipmentID = "UlEvGetEquipmentId"
48 UlEvGetFirstSwVersion = "UlEvGetFirstSwVersion"
49 UlEvGetSecondSwVersion = "UlEvGetSecondSwVersion"
50 UlEvGetMacAddress = "UlEvGetMacAddress"
51 UlEvGetMibTemplate = "UlEvGetMibTemplate"
52 UlEvUploadMib = "UlEvUploadMib"
53 UlEvExamineMds = "UlEvExamineMds"
54 UlEvSuccess = "UlEvSuccess"
55 UlEvMismatch = "UlEvMismatch"
56 UlEvAuditMib = "UlEvAuditMib"
57 UlEvForceResync = "UlEvForceResync"
58 UlEvDiffsFound = "UlEvDiffsFound"
59 UlEvTimeout = "UlEvTimeout"
60 UlEvStop = "UlEvStop"
61)
62
63// states of MibUpload FSM
64const (
65 UlStDisabled = "UlStDisabled"
66 UlStStarting = "UlStStarting"
67 UlStResettingMib = "UlStResettingMib"
68 UlStGettingVendorAndSerial = "UlStGettingVendorAndSerial"
69 UlStGettingEquipmentID = "UlStGettingEquipmentID"
70 UlStGettingFirstSwVersion = "UlStGettingFirstSwVersion"
71 UlStGettingSecondSwVersion = "UlStGettingSecondSwVersion"
72 UlStGettingMacAddress = "UlStGettingMacAddress"
73 UlStGettingMibTemplate = "UlStGettingMibTemplate"
74 UlStUploading = "UlStUploading"
75 UlStUploadDone = "UlStUploadDone"
76 UlStInSync = "UlStInSync"
77 UlStExaminingMds = "UlStExaminingMds"
78 UlStResynchronizing = "UlStResynchronizing"
79 UlStExaminingMdsSuccess = "UlStExaminingMdsSuccess"
80 UlStAuditing = "UlStAuditing"
81 UlStReAuditing = "UlStReAuditing"
82 UlStOutOfSync = "UlStOutOfSync"
83)
84
85// CMibUlFsmIdleState - TODO: add comment
86const CMibUlFsmIdleState = UlStInSync
87
88// events of MibDownload FSM
89const (
90 DlEvStart = "DlEvStart"
91 DlEvCreateGal = "DlEvCreateGal"
92 DlEvRxGalResp = "DlEvRxGalResp"
93 DlEvRxOnu2gResp = "DlEvRxOnu2gResp"
94 DlEvRxBridgeResp = "DlEvRxBridgeResp"
95 DlEvTimeoutSimple = "DlEvTimeoutSimple"
96 DlEvTimeoutBridge = "DlEvTimeoutBridge"
97 DlEvReset = "DlEvReset"
98 DlEvRestart = "DlEvRestart"
99)
100
101// states of MibDownload FSM
102const (
103 DlStDisabled = "DlStDisabled"
104 DlStStarting = "DlStStarting"
105 DlStCreatingGal = "DlStCreatingGal"
106 DlStSettingOnu2g = "DlStSettingOnu2g"
107 DlStBridgeInit = "DlStBridgeInit"
108 DlStDownloaded = "DlStDownloaded"
109 DlStResetting = "DlStResetting"
110)
111
112// CMibDlFsmIdleState - TODO: add comment
113const CMibDlFsmIdleState = DlStDisabled
114
115const (
116 // NOTE that this hardcoded to service/voltha as the MIB template is shared across stacks
117 cBasePathMibTemplateKvStore = "service/voltha/omci_mibs/go_templates"
118 cSuffixMibTemplateKvStore = "%s/%s/%s"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000119)
120
121const cEmptyMacAddrString = "000000000000"
122const cEmptySerialNumberString = "0000000000000000"
123
124type uniPersConfig struct {
125 PersUniID uint8 `json:"uni_id"`
126 PersTpPathMap map[uint8]string `json:"PersTpPathMap"` // tp-id to tp-path map
127 PersFlowParams []cmn.UniVlanFlowParams `json:"flow_params"` //as defined in omci_ani_config.go
128}
129
130type onuPersistentData struct {
131 PersOnuID uint32 `json:"onu_id"`
132 PersIntfID uint32 `json:"intf_id"`
133 PersSerialNumber string `json:"serial_number"`
134 PersMacAddress string `json:"mac_address"`
135 PersVendorID string `json:"vendor_id"`
136 PersEquipmentID string `json:"equipment_id"`
137 PersActiveSwVersion string `json:"active_sw_version"`
138 PersAdminState string `json:"admin_state"`
139 PersOperState string `json:"oper_state"`
140 PersUniUnlockDone bool `json:"uni_unlock_done"`
141 PersUniDisableDone bool `json:"uni_disable_done"`
142 PersMibAuditInterval time.Duration `json:"mib_audit_interval"`
143 PersMibLastDbSync uint32 `json:"mib_last_db_sync"`
144 PersMibDataSyncAdpt uint8 `json:"mib_data_sync_adpt"`
145 PersUniConfig []uniPersConfig `json:"uni_config"`
146 PersAlarmAuditInterval time.Duration `json:"alarm_audit_interval"`
147 PersTcontMap map[uint16]uint16 `json:"tcont_map"` //alloc-id to me-instance-id map
148}
149
150// OnuDeviceEntry - ONU device info and FSM events.
151type OnuDeviceEntry struct {
152 deviceID string
153 baseDeviceHandler cmn.IdeviceHandler
154 pOpenOnuAc cmn.IopenONUAC
155 pOnuTP cmn.IonuUniTechProf
156 coreClient *vgrpc.Client
157 PDevOmciCC *cmn.OmciCC
158 pOnuDB *devdb.OnuDeviceDB
159 mibTemplateKVStore *db.Backend
160 MutexPersOnuConfig sync.RWMutex
161 SOnuPersistentData onuPersistentData
162 reconcilingFlows bool
163 mutexReconcilingFlowsFlag sync.RWMutex
164 chReconcilingFlowsFinished chan bool //channel to indicate that reconciling of flows has been finished
165 mibTemplatePath string
166 mutexOnuKVStore sync.RWMutex
167 onuKVStore *db.Backend
168 onuKVStorePath string
169 mutexOnuKVStoreProcResult sync.RWMutex
170 onuKVStoreProcResult error //error indication of processing
171 chOnuKvProcessingStep chan uint8
172 mutexOnuSwImageIndications sync.RWMutex
173 onuSwImageIndications cmn.SswImageIndications
174 MutexOnuImageStatus sync.RWMutex
175 POnuImageStatus *swupg.OnuImageStatus
176 //lockDeviceEntries sync.RWMutex
177 mibDbClass func(context.Context) error
178 supportedFsms cmn.OmciDeviceFsms
179 devState cmn.OnuDeviceEvent
180 // Audit and MDS
181 mibAuditInterval time.Duration
182 alarmAuditInterval time.Duration
183 // TODO: periodical mib resync will be implemented with story VOL-3792
184 //mibNextDbResync uint32
185
186 // for mibUpload
187 PMibUploadFsm *cmn.AdapterFsm //could be handled dynamically and more general as pcmn.AdapterFsm - perhaps later
188 mutexLastTxParamStruct sync.RWMutex
189 lastTxParamStruct sLastTxMeParameter
190 // for mibDownload
191 PMibDownloadFsm *cmn.AdapterFsm //could be handled dynamically and more general as pcmn.AdapterFsm - perhaps later
192 //remark: general usage of pAdapterFsm would require generalization of CommChan usage and internal event setting
193 // within the FSM event procedures
194 mutexPLastTxMeInstance sync.RWMutex
195 pLastTxMeInstance *me.ManagedEntity
196 omciMessageReceived chan bool //seperate channel needed by DownloadFsm
197 omciRebootMessageReceivedChannel chan cmn.Message // channel needed by reboot request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000198}
199
200//NewOnuDeviceEntry returns a new instance of a OnuDeviceEntry
201//mib_db (as well as not inluded alarm_db not really used in this code? VERIFY!!)
202func NewOnuDeviceEntry(ctx context.Context, cc *vgrpc.Client, dh cmn.IdeviceHandler,
203 openonu cmn.IopenONUAC) *OnuDeviceEntry {
204 var onuDeviceEntry OnuDeviceEntry
205 onuDeviceEntry.deviceID = dh.GetDeviceID()
206 logger.Debugw(ctx, "init-onuDeviceEntry", log.Fields{"device-id": onuDeviceEntry.deviceID})
207 onuDeviceEntry.baseDeviceHandler = dh
208 onuDeviceEntry.pOpenOnuAc = openonu
209 onuDeviceEntry.coreClient = cc
210 onuDeviceEntry.devState = cmn.DeviceStatusInit
211 onuDeviceEntry.SOnuPersistentData.PersUniConfig = make([]uniPersConfig, 0)
212 onuDeviceEntry.SOnuPersistentData.PersTcontMap = make(map[uint16]uint16)
213 onuDeviceEntry.chReconcilingFlowsFinished = make(chan bool)
214 onuDeviceEntry.reconcilingFlows = false
215 onuDeviceEntry.chOnuKvProcessingStep = make(chan uint8)
216 onuDeviceEntry.omciRebootMessageReceivedChannel = make(chan cmn.Message, 2048)
217 //openomciagent.lockDeviceHandlersMap = sync.RWMutex{}
218 //OMCI related databases are on a per-agent basis. State machines and tasks
219 //are per ONU Vendor
220 //
221 // MIB Synchronization Database - possible overloading from arguments
222 supportedFsms := onuDeviceEntry.pOpenOnuAc.GetSupportedFsms()
223 if supportedFsms != nil {
224 onuDeviceEntry.supportedFsms = *supportedFsms
225 } else {
226 // This branch is currently not used and is for potential future usage of alternative MIB Sync FSMs only!
227 //var mibSyncFsm = NewMibSynchronizer()
228 // use some internal defaults, if not defined from outside
229 onuDeviceEntry.supportedFsms = cmn.OmciDeviceFsms{
230 "mib-synchronizer": {
231 //mibSyncFsm, // Implements the MIB synchronization state machine
232 DatabaseClass: onuDeviceEntry.mibDbVolatileDict, // Implements volatile ME MIB database
233 //true, // Advertise events on OpenOMCI event bus
234 AuditInterval: dh.GetAlarmAuditInterval(), // Time to wait between MIB audits. 0 to disable audits.
235 // map[string]func() error{
236 // "mib-upload": onuDeviceEntry.MibUploadTask,
237 // "mib-template": onuDeviceEntry.MibTemplateTask,
238 // "get-mds": onuDeviceEntry.GetMdsTask,
239 // "mib-audit": onuDeviceEntry.GetMdsTask,
240 // "mib-resync": onuDeviceEntry.MibResyncTask,
241 // "mib-reconcile": onuDeviceEntry.MibReconcileTask,
242 // },
243 },
244 }
245 }
246 onuDeviceEntry.mibDbClass = onuDeviceEntry.supportedFsms["mib-synchronizer"].DatabaseClass
247 logger.Debug(ctx, "access2mibDbClass")
248 go onuDeviceEntry.mibDbClass(ctx)
249 if !dh.IsReconciling() {
250 onuDeviceEntry.mibAuditInterval = onuDeviceEntry.supportedFsms["mib-synchronizer"].AuditInterval
251 onuDeviceEntry.SOnuPersistentData.PersMibAuditInterval = onuDeviceEntry.mibAuditInterval
252 onuDeviceEntry.alarmAuditInterval = dh.GetAlarmAuditInterval()
253 onuDeviceEntry.SOnuPersistentData.PersAlarmAuditInterval = onuDeviceEntry.alarmAuditInterval
254 } else {
255 logger.Debugw(ctx, "reconciling - take audit interval from persistent data", log.Fields{"device-id": onuDeviceEntry.deviceID})
256 // TODO: This is a preparation for VOL-VOL-3811 to preserve config history in case of
257 // vendor- or deviceID-specific configurations via voltctl-commands
258 onuDeviceEntry.mibAuditInterval = onuDeviceEntry.SOnuPersistentData.PersMibAuditInterval
259 onuDeviceEntry.alarmAuditInterval = onuDeviceEntry.SOnuPersistentData.PersAlarmAuditInterval
260 }
261 logger.Debugw(ctx, "MibAuditInterval and AlarmAuditInterval is set to", log.Fields{"mib-audit-interval": onuDeviceEntry.mibAuditInterval,
262 "alarm-audit-interval": onuDeviceEntry.alarmAuditInterval})
263 // TODO: periodical mib resync will be implemented with story VOL-3792
264 //onuDeviceEntry.mibNextDbResync = 0
265
266 // Omci related Mib upload sync state machine
267 mibUploadChan := make(chan cmn.Message, 2048)
268 onuDeviceEntry.PMibUploadFsm = cmn.NewAdapterFsm("MibUpload", onuDeviceEntry.deviceID, mibUploadChan)
269 onuDeviceEntry.PMibUploadFsm.PFsm = fsm.NewFSM(
270 UlStDisabled,
271 fsm.Events{
272
273 {Name: UlEvStart, Src: []string{UlStDisabled}, Dst: UlStStarting},
274
275 {Name: UlEvResetMib, Src: []string{UlStStarting}, Dst: UlStResettingMib},
276 {Name: UlEvGetVendorAndSerial, Src: []string{UlStResettingMib}, Dst: UlStGettingVendorAndSerial},
277 {Name: UlEvGetEquipmentID, Src: []string{UlStGettingVendorAndSerial}, Dst: UlStGettingEquipmentID},
278 {Name: UlEvGetFirstSwVersion, Src: []string{UlStGettingEquipmentID}, Dst: UlStGettingFirstSwVersion},
279 {Name: UlEvGetSecondSwVersion, Src: []string{UlStGettingFirstSwVersion}, Dst: UlStGettingSecondSwVersion},
280 {Name: UlEvGetMacAddress, Src: []string{UlStGettingSecondSwVersion}, Dst: UlStGettingMacAddress},
281 {Name: UlEvGetMibTemplate, Src: []string{UlStGettingMacAddress}, Dst: UlStGettingMibTemplate},
282
283 {Name: UlEvUploadMib, Src: []string{UlStGettingMibTemplate}, Dst: UlStUploading},
284 {Name: UlEvExamineMds, Src: []string{UlStStarting}, Dst: UlStExaminingMds},
285
286 {Name: UlEvSuccess, Src: []string{UlStGettingMibTemplate}, Dst: UlStUploadDone},
287 {Name: UlEvSuccess, Src: []string{UlStUploading}, Dst: UlStUploadDone},
288
289 {Name: UlEvSuccess, Src: []string{UlStUploadDone}, Dst: UlStInSync},
290 //{Name: UlEvSuccess, Src: []string{UlStExaminingMds}, Dst: UlStInSync},
291 {Name: UlEvSuccess, Src: []string{UlStExaminingMds}, Dst: UlStExaminingMdsSuccess},
292 // TODO: As long as mib-resynchronizing is not implemented, failed MDS-examination triggers
293 // mib-reset and new provisioning at this point
294 //{Name: UlEvMismatch, Src: []string{UlStExaminingMds}, Dst: UlStResynchronizing},
295 {Name: UlEvMismatch, Src: []string{UlStExaminingMds}, Dst: UlStResettingMib},
296
297 {Name: UlEvSuccess, Src: []string{UlStExaminingMdsSuccess}, Dst: UlStInSync},
298 {Name: UlEvMismatch, Src: []string{UlStExaminingMdsSuccess}, Dst: UlStResettingMib},
299
300 {Name: UlEvAuditMib, Src: []string{UlStInSync}, Dst: UlStAuditing},
301
302 {Name: UlEvSuccess, Src: []string{UlStOutOfSync}, Dst: UlStInSync},
303 {Name: UlEvAuditMib, Src: []string{UlStOutOfSync}, Dst: UlStAuditing},
304
305 {Name: UlEvSuccess, Src: []string{UlStAuditing}, Dst: UlStInSync},
306 {Name: UlEvMismatch, Src: []string{UlStAuditing}, Dst: UlStReAuditing},
307 {Name: UlEvForceResync, Src: []string{UlStAuditing}, Dst: UlStResynchronizing},
308
309 {Name: UlEvSuccess, Src: []string{UlStReAuditing}, Dst: UlStInSync},
310 {Name: UlEvMismatch, Src: []string{UlStReAuditing}, Dst: UlStResettingMib},
311
312 {Name: UlEvSuccess, Src: []string{UlStResynchronizing}, Dst: UlStInSync},
313 {Name: UlEvDiffsFound, Src: []string{UlStResynchronizing}, Dst: UlStOutOfSync},
314
315 {Name: UlEvTimeout, Src: []string{UlStResettingMib, UlStGettingVendorAndSerial, UlStGettingEquipmentID, UlStGettingFirstSwVersion,
316 UlStGettingSecondSwVersion, UlStGettingMacAddress, UlStGettingMibTemplate, UlStUploading, UlStResynchronizing, UlStExaminingMds,
317 UlStUploadDone, UlStInSync, UlStOutOfSync, UlStAuditing, UlStReAuditing}, Dst: UlStStarting},
318
319 {Name: UlEvStop, Src: []string{UlStStarting, UlStResettingMib, UlStGettingVendorAndSerial, UlStGettingEquipmentID, UlStGettingFirstSwVersion,
320 UlStGettingSecondSwVersion, UlStGettingMacAddress, UlStGettingMibTemplate, UlStUploading, UlStResynchronizing, UlStExaminingMds,
321 UlStUploadDone, UlStInSync, UlStOutOfSync, UlStAuditing, UlStReAuditing}, Dst: UlStDisabled},
322 },
323
324 fsm.Callbacks{
325 "enter_state": func(e *fsm.Event) { onuDeviceEntry.PMibUploadFsm.LogFsmStateChange(ctx, e) },
326 "enter_" + UlStStarting: func(e *fsm.Event) { onuDeviceEntry.enterStartingState(ctx, e) },
327 "enter_" + UlStResettingMib: func(e *fsm.Event) { onuDeviceEntry.enterResettingMibState(ctx, e) },
328 "enter_" + UlStGettingVendorAndSerial: func(e *fsm.Event) { onuDeviceEntry.enterGettingVendorAndSerialState(ctx, e) },
329 "enter_" + UlStGettingEquipmentID: func(e *fsm.Event) { onuDeviceEntry.enterGettingEquipmentIDState(ctx, e) },
330 "enter_" + UlStGettingFirstSwVersion: func(e *fsm.Event) { onuDeviceEntry.enterGettingFirstSwVersionState(ctx, e) },
331 "enter_" + UlStGettingSecondSwVersion: func(e *fsm.Event) { onuDeviceEntry.enterGettingSecondSwVersionState(ctx, e) },
332 "enter_" + UlStGettingMacAddress: func(e *fsm.Event) { onuDeviceEntry.enterGettingMacAddressState(ctx, e) },
333 "enter_" + UlStGettingMibTemplate: func(e *fsm.Event) { onuDeviceEntry.enterGettingMibTemplateState(ctx, e) },
334 "enter_" + UlStUploading: func(e *fsm.Event) { onuDeviceEntry.enterUploadingState(ctx, e) },
335 "enter_" + UlStUploadDone: func(e *fsm.Event) { onuDeviceEntry.enterUploadDoneState(ctx, e) },
336 "enter_" + UlStExaminingMds: func(e *fsm.Event) { onuDeviceEntry.enterExaminingMdsState(ctx, e) },
337 "enter_" + UlStResynchronizing: func(e *fsm.Event) { onuDeviceEntry.enterResynchronizingState(ctx, e) },
338 "enter_" + UlStExaminingMdsSuccess: func(e *fsm.Event) { onuDeviceEntry.enterExaminingMdsSuccessState(ctx, e) },
339 "enter_" + UlStAuditing: func(e *fsm.Event) { onuDeviceEntry.enterAuditingState(ctx, e) },
340 "enter_" + UlStReAuditing: func(e *fsm.Event) { onuDeviceEntry.enterReAuditingState(ctx, e) },
341 "enter_" + UlStOutOfSync: func(e *fsm.Event) { onuDeviceEntry.enterOutOfSyncState(ctx, e) },
342 "enter_" + UlStInSync: func(e *fsm.Event) { onuDeviceEntry.enterInSyncState(ctx, e) },
343 },
344 )
345 // Omci related Mib download state machine
346 mibDownloadChan := make(chan cmn.Message, 2048)
347 onuDeviceEntry.PMibDownloadFsm = cmn.NewAdapterFsm("MibDownload", onuDeviceEntry.deviceID, mibDownloadChan)
348 onuDeviceEntry.PMibDownloadFsm.PFsm = fsm.NewFSM(
349 DlStDisabled,
350 fsm.Events{
351
352 {Name: DlEvStart, Src: []string{DlStDisabled}, Dst: DlStStarting},
353
354 {Name: DlEvCreateGal, Src: []string{DlStStarting}, Dst: DlStCreatingGal},
355 {Name: DlEvRxGalResp, Src: []string{DlStCreatingGal}, Dst: DlStSettingOnu2g},
356 {Name: DlEvRxOnu2gResp, Src: []string{DlStSettingOnu2g}, Dst: DlStBridgeInit},
357 // the bridge state is used for multi ME config for alle UNI related ports
358 // maybe such could be reflected in the state machine as well (port number parametrized)
359 // but that looks not straightforward here - so we keep it simple here for the beginning(?)
360 {Name: DlEvRxBridgeResp, Src: []string{DlStBridgeInit}, Dst: DlStDownloaded},
361
362 {Name: DlEvTimeoutSimple, Src: []string{DlStCreatingGal, DlStSettingOnu2g}, Dst: DlStStarting},
363 {Name: DlEvTimeoutBridge, Src: []string{DlStBridgeInit}, Dst: DlStStarting},
364
365 {Name: DlEvReset, Src: []string{DlStStarting, DlStCreatingGal, DlStSettingOnu2g,
366 DlStBridgeInit, DlStDownloaded}, Dst: DlStResetting},
367 // exceptional treatment for all states except DlStResetting
368 {Name: DlEvRestart, Src: []string{DlStStarting, DlStCreatingGal, DlStSettingOnu2g,
369 DlStBridgeInit, DlStDownloaded, DlStResetting}, Dst: DlStDisabled},
370 },
371
372 fsm.Callbacks{
373 "enter_state": func(e *fsm.Event) { onuDeviceEntry.PMibDownloadFsm.LogFsmStateChange(ctx, e) },
374 "enter_" + DlStStarting: func(e *fsm.Event) { onuDeviceEntry.enterDLStartingState(ctx, e) },
375 "enter_" + DlStCreatingGal: func(e *fsm.Event) { onuDeviceEntry.enterCreatingGalState(ctx, e) },
376 "enter_" + DlStSettingOnu2g: func(e *fsm.Event) { onuDeviceEntry.enterSettingOnu2gState(ctx, e) },
377 "enter_" + DlStBridgeInit: func(e *fsm.Event) { onuDeviceEntry.enterBridgeInitState(ctx, e) },
378 "enter_" + DlStDownloaded: func(e *fsm.Event) { onuDeviceEntry.enterDownloadedState(ctx, e) },
379 "enter_" + DlStResetting: func(e *fsm.Event) { onuDeviceEntry.enterResettingState(ctx, e) },
380 },
381 )
382 if onuDeviceEntry.PMibDownloadFsm == nil || onuDeviceEntry.PMibDownloadFsm.PFsm == nil {
383 logger.Errorw(ctx, "MibDownloadFsm could not be instantiated", log.Fields{"device-id": onuDeviceEntry.deviceID})
384 // TODO some specific error treatment - or waiting for crash ?
385 }
386
387 onuDeviceEntry.mibTemplateKVStore = onuDeviceEntry.baseDeviceHandler.SetBackend(ctx, cBasePathMibTemplateKvStore)
388 if onuDeviceEntry.mibTemplateKVStore == nil {
389 logger.Errorw(ctx, "Can't access mibTemplateKVStore - no backend connection to service",
390 log.Fields{"device-id": onuDeviceEntry.deviceID, "service": cBasePathMibTemplateKvStore})
391 }
392
393 onuDeviceEntry.onuKVStorePath = onuDeviceEntry.deviceID
Holger Hildebrandt60652202021-11-02 11:09:36 +0000394 baseKvStorePath := fmt.Sprintf(cmn.CBasePathOnuKVStore, dh.GetBackendPathPrefix())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000395 onuDeviceEntry.onuKVStore = onuDeviceEntry.baseDeviceHandler.SetBackend(ctx, baseKvStorePath)
396 if onuDeviceEntry.onuKVStore == nil {
397 logger.Errorw(ctx, "Can't access onuKVStore - no backend connection to service",
398 log.Fields{"device-id": onuDeviceEntry.deviceID, "service": baseKvStorePath})
399 }
400
401 // Alarm Synchronization Database
402
403 //self._alarm_db = None
404 //self._alarm_database_cls = support_classes['alarm-synchronizer']['database']
405 return &onuDeviceEntry
406}
407
408//Start starts (logs) the omci agent
409func (oo *OnuDeviceEntry) Start(ctx context.Context) error {
410 logger.Debugw(ctx, "OnuDeviceEntry-starting", log.Fields{"for device-id": oo.deviceID})
411 if oo.PDevOmciCC == nil {
412 oo.PDevOmciCC = cmn.NewOmciCC(ctx, oo.deviceID, oo.baseDeviceHandler, oo, oo.baseDeviceHandler.GetOnuAlarmManager(), oo.coreClient)
413 if oo.PDevOmciCC == nil {
414 logger.Errorw(ctx, "Could not create devOmciCc - abort", log.Fields{"for device-id": oo.deviceID})
415 return fmt.Errorf("could not create devOmciCc %s", oo.deviceID)
416 }
417 }
418 return nil
419}
420
421//Stop stops/resets the omciCC
422func (oo *OnuDeviceEntry) Stop(ctx context.Context, abResetOmciCC bool) error {
423 logger.Debugw(ctx, "OnuDeviceEntry-stopping", log.Fields{"for device-id": oo.deviceID})
424 if abResetOmciCC && (oo.PDevOmciCC != nil) {
425 _ = oo.PDevOmciCC.Stop(ctx)
426 }
427 //to allow for all event notifications again when re-using the device and omciCC
428 oo.devState = cmn.DeviceStatusInit
429 return nil
430}
431
432// Reboot - TODO: add comment
433func (oo *OnuDeviceEntry) Reboot(ctx context.Context) error {
434 logger.Debugw(ctx, "OnuDeviceEntry-rebooting", log.Fields{"for device-id": oo.deviceID})
435 if oo.PDevOmciCC != nil {
436 if err := oo.PDevOmciCC.SendReboot(ctx, oo.baseDeviceHandler.GetOmciTimeout(), true, oo.omciRebootMessageReceivedChannel); err != nil {
437 logger.Errorw(ctx, "onu didn't reboot", log.Fields{"for device-id": oo.deviceID})
438 return err
439 }
440 }
441 return nil
442}
443
444// WaitForRebootResponse - TODO: add comment
445func (oo *OnuDeviceEntry) WaitForRebootResponse(ctx context.Context, responseChannel chan cmn.Message) error {
446 select {
447 case <-time.After(oo.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
448 logger.Warnw(ctx, "reboot timeout", log.Fields{"for device-id": oo.deviceID})
449 return fmt.Errorf("rebootTimeout")
450 case data := <-responseChannel:
451 switch data.Data.(cmn.OmciMessage).OmciMsg.MessageType {
452 case omci.RebootResponseType:
453 {
454 msgLayer := (*data.Data.(cmn.OmciMessage).OmciPacket).Layer(omci.LayerTypeRebootResponse)
455 if msgLayer == nil {
456 return fmt.Errorf("omci Msg layer could not be detected for RebootResponseType")
457 }
458 msgObj, msgOk := msgLayer.(*omci.RebootResponse)
459 if !msgOk {
460 return fmt.Errorf("omci Msg layer could not be assigned for RebootResponseType %s", oo.deviceID)
461 }
462 logger.Debugw(ctx, "RebootResponse data", log.Fields{"device-id": oo.deviceID, "data-fields": msgObj})
463 if msgObj.Result != me.Success {
464 logger.Errorw(ctx, "Omci RebootResponse result error", log.Fields{"device-id": oo.deviceID, "Error": msgObj.Result})
465 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
466 return fmt.Errorf("omci RebootResponse result error indication %s for device %s",
467 msgObj.Result, oo.deviceID)
468 }
469 return nil
470 }
471 }
472 logger.Warnw(ctx, "Reboot response message type error", log.Fields{"for device-id": oo.deviceID})
473 return fmt.Errorf("unexpected OmciResponse type received %s", oo.deviceID)
474 }
475}
476
477//Relay the InSync message via Handler to Rw core - Status update
478func (oo *OnuDeviceEntry) transferSystemEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
479 logger.Debugw(ctx, "relaying system-event", log.Fields{"Event": devEvent})
480 // decouple the handler transfer from further processing here
481 // TODO!!! check if really no synch is required within the system e.g. to ensure following steps ..
482 if devEvent == cmn.MibDatabaseSync {
483 if oo.devState < cmn.MibDatabaseSync { //devState has not been synced yet
484 oo.devState = cmn.MibDatabaseSync
485 go oo.baseDeviceHandler.DeviceProcStatusUpdate(ctx, devEvent)
486 //TODO!!! device control: next step: start MIB capability verification from here ?!!!
487 } else {
488 logger.Debugw(ctx, "mibinsync-event in some already synced state - ignored", log.Fields{"state": oo.devState})
489 }
490 } else if devEvent == cmn.MibDownloadDone {
491 if oo.devState < cmn.MibDownloadDone { //devState has not been synced yet
492 oo.devState = cmn.MibDownloadDone
493 go oo.baseDeviceHandler.DeviceProcStatusUpdate(ctx, devEvent)
494 } else {
495 logger.Debugw(ctx, "mibdownloaddone-event was already seen - ignored", log.Fields{"state": oo.devState})
496 }
497 } else {
498 logger.Warnw(ctx, "device-event not yet handled", log.Fields{"state": devEvent})
499 }
500}
501
502// RestoreDataFromOnuKvStore - TODO: add comment
503func (oo *OnuDeviceEntry) RestoreDataFromOnuKvStore(ctx context.Context) error {
504 if oo.onuKVStore == nil {
505 logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
506 return fmt.Errorf(fmt.Sprintf("onuKVStore-not-set-abort-%s", oo.deviceID))
507 }
508 oo.MutexPersOnuConfig.Lock()
509 defer oo.MutexPersOnuConfig.Unlock()
510 oo.SOnuPersistentData =
511 onuPersistentData{0, 0, "", "", "", "", "", "", "", false, false, oo.mibAuditInterval, 0, 0, make([]uniPersConfig, 0), oo.alarmAuditInterval, make(map[uint16]uint16)}
512 oo.mutexOnuKVStore.RLock()
513 Value, err := oo.onuKVStore.Get(ctx, oo.onuKVStorePath)
514 oo.mutexOnuKVStore.RUnlock()
515 if err == nil {
516 if Value != nil {
517 logger.Debugw(ctx, "ONU-data read",
518 log.Fields{"Key": Value.Key, "device-id": oo.deviceID})
519 tmpBytes, _ := kvstore.ToByte(Value.Value)
520
521 if err = json.Unmarshal(tmpBytes, &oo.SOnuPersistentData); err != nil {
522 logger.Errorw(ctx, "unable to unmarshal ONU-data", log.Fields{"error": err, "device-id": oo.deviceID})
523 return fmt.Errorf(fmt.Sprintf("unable-to-unmarshal-ONU-data-%s", oo.deviceID))
524 }
525 logger.Debugw(ctx, "ONU-data", log.Fields{"SOnuPersistentData": oo.SOnuPersistentData,
526 "device-id": oo.deviceID})
527 } else {
528 logger.Debugw(ctx, "no ONU-data found", log.Fields{"path": oo.onuKVStorePath, "device-id": oo.deviceID})
529 return fmt.Errorf("no-ONU-data-found")
530 }
531 } else {
532 logger.Errorw(ctx, "unable to read from KVstore", log.Fields{"device-id": oo.deviceID})
533 return fmt.Errorf(fmt.Sprintf("unable-to-read-from-KVstore-%s", oo.deviceID))
534 }
535 return nil
536}
537
538// DeleteDataFromOnuKvStore - TODO: add comment
539func (oo *OnuDeviceEntry) DeleteDataFromOnuKvStore(ctx context.Context, wg *sync.WaitGroup) {
540 defer wg.Done()
541
542 if oo.onuKVStore == nil {
543 logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
544 oo.setKvProcessingErrorIndication(errors.New("onu-data delete aborted: onuKVStore not set"))
545 return
546 }
547 var processingStep uint8 = 1 // used to synchronize the different processing steps with chOnuKvProcessingStep
548 go oo.deletePersistentData(ctx, processingStep)
549 if !oo.waitForTimeoutOrCompletion(ctx, oo.chOnuKvProcessingStep, processingStep) {
550 //timeout or error detected
551 logger.Debugw(ctx, "ONU-data not deleted - abort", log.Fields{"device-id": oo.deviceID})
552 oo.setKvProcessingErrorIndication(errors.New("onu-data delete aborted: during kv-access"))
553 return
554 }
555}
556
557func (oo *OnuDeviceEntry) deletePersistentData(ctx context.Context, aProcessingStep uint8) {
558
559 logger.Debugw(ctx, "delete and clear internal persistency data", log.Fields{"device-id": oo.deviceID})
560
561 oo.MutexPersOnuConfig.Lock()
562 defer oo.MutexPersOnuConfig.Unlock()
563
564 oo.SOnuPersistentData.PersUniConfig = nil //releasing all UniConfig entries to garbage collector default entry
565 oo.SOnuPersistentData =
566 onuPersistentData{0, 0, "", "", "", "", "", "", "", false, false, oo.mibAuditInterval, 0, 0, make([]uniPersConfig, 0), oo.alarmAuditInterval, make(map[uint16]uint16)}
567 logger.Debugw(ctx, "delete ONU-data from KVStore", log.Fields{"device-id": oo.deviceID})
568 oo.mutexOnuKVStore.Lock()
569 err := oo.onuKVStore.Delete(ctx, oo.onuKVStorePath)
570 oo.mutexOnuKVStore.Unlock()
571 if err != nil {
572 logger.Errorw(ctx, "unable to delete in KVstore", log.Fields{"device-id": oo.deviceID, "err": err})
573 oo.chOnuKvProcessingStep <- 0 //error indication
574 return
575 }
576 oo.chOnuKvProcessingStep <- aProcessingStep //done
577}
578
579// UpdateOnuKvStore - TODO: add comment
580func (oo *OnuDeviceEntry) UpdateOnuKvStore(ctx context.Context, wg *sync.WaitGroup) {
581 defer wg.Done()
582
583 if oo.onuKVStore == nil {
584 logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
585 oo.setKvProcessingErrorIndication(errors.New("onu-data update aborted: onuKVStore not set"))
586 return
587 }
588 var processingStep uint8 = 1 // used to synchronize the different processing steps with chOnuKvProcessingStep
589 go oo.storeDataInOnuKvStore(ctx, processingStep)
590 if !oo.waitForTimeoutOrCompletion(ctx, oo.chOnuKvProcessingStep, processingStep) {
591 //timeout or error detected
592 logger.Debugw(ctx, "ONU-data not written - abort", log.Fields{"device-id": oo.deviceID})
593 oo.setKvProcessingErrorIndication(errors.New("onu-data update aborted: during writing process"))
594 return
595 }
596}
597
598func (oo *OnuDeviceEntry) storeDataInOnuKvStore(ctx context.Context, aProcessingStep uint8) {
599
600 oo.MutexPersOnuConfig.Lock()
601 defer oo.MutexPersOnuConfig.Unlock()
602 //assign values which are not already present when NewOnuDeviceEntry() is called
603 onuIndication := oo.baseDeviceHandler.GetOnuIndication()
604 oo.SOnuPersistentData.PersOnuID = onuIndication.OnuId
605 oo.SOnuPersistentData.PersIntfID = onuIndication.IntfId
606 //TODO: verify usage of these values during restart UC
607 oo.SOnuPersistentData.PersAdminState = onuIndication.AdminState
608 oo.SOnuPersistentData.PersOperState = onuIndication.OperState
609
610 logger.Debugw(ctx, "Update ONU-data in KVStore", log.Fields{"device-id": oo.deviceID, "SOnuPersistentData": oo.SOnuPersistentData})
611
612 Value, err := json.Marshal(oo.SOnuPersistentData)
613 if err != nil {
614 logger.Errorw(ctx, "unable to marshal ONU-data", log.Fields{"SOnuPersistentData": oo.SOnuPersistentData,
615 "device-id": oo.deviceID, "err": err})
616 oo.chOnuKvProcessingStep <- 0 //error indication
617 return
618 }
619 oo.pOpenOnuAc.RLockMutexDeviceHandlersMap()
620 if _, exist := oo.pOpenOnuAc.GetDeviceHandler(oo.deviceID); !exist {
621 logger.Debugw(ctx, "delete_device in progress - skip write request", log.Fields{"device-id": oo.deviceID})
622 oo.chOnuKvProcessingStep <- aProcessingStep
623 oo.pOpenOnuAc.RUnlockMutexDeviceHandlersMap()
624 return
625 }
626 oo.baseDeviceHandler.RLockMutexDeletionInProgressFlag()
627 if oo.baseDeviceHandler.GetDeletionInProgress() {
628 logger.Debugw(ctx, "delete_device in progress - skip write request", log.Fields{"device-id": oo.deviceID})
629 oo.chOnuKvProcessingStep <- aProcessingStep
630 oo.pOpenOnuAc.RUnlockMutexDeviceHandlersMap()
631 oo.baseDeviceHandler.RUnlockMutexDeletionInProgressFlag()
632 return
633 }
634 oo.pOpenOnuAc.RUnlockMutexDeviceHandlersMap()
635 oo.baseDeviceHandler.RUnlockMutexDeletionInProgressFlag()
636
637 oo.mutexOnuKVStore.Lock()
638 err = oo.onuKVStore.Put(ctx, oo.onuKVStorePath, Value)
639 oo.mutexOnuKVStore.Unlock()
640 if err != nil {
641 logger.Errorw(ctx, "unable to write ONU-data into KVstore", log.Fields{"device-id": oo.deviceID, "err": err})
642 oo.chOnuKvProcessingStep <- 0 //error indication
643 return
644 }
645 oo.chOnuKvProcessingStep <- aProcessingStep //done
646}
647
648// UpdateOnuUniTpPath - TODO: add comment
649func (oo *OnuDeviceEntry) UpdateOnuUniTpPath(ctx context.Context, aUniID uint8, aTpID uint8, aPathString string) bool {
650 /* within some specific InterAdapter processing request write/read access to data is ensured to be sequentially,
651 as also the complete sequence is ensured to 'run to completion' before some new request is accepted
652 no specific concurrency protection to SOnuPersistentData is required here
653 */
654 oo.MutexPersOnuConfig.Lock()
655 defer oo.MutexPersOnuConfig.Unlock()
656
657 for k, v := range oo.SOnuPersistentData.PersUniConfig {
658 if v.PersUniID == aUniID {
659 existingPath, ok := oo.SOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID]
660 logger.Debugw(ctx, "PersUniConfig-entry exists", log.Fields{"device-id": oo.deviceID, "uniID": aUniID,
661 "tpID": aTpID, "path": aPathString, "existingPath": existingPath, "ok": ok})
662 if !ok {
663 logger.Debugw(ctx, "tp-does-not-exist", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "tpID": aTpID, "path": aPathString})
664 }
665 if existingPath != aPathString {
666 if aPathString == "" {
667 //existing entry to be deleted
668 logger.Debugw(ctx, "UniTp delete path value", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
669 oo.SOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID] = ""
670 } else {
671 //existing entry to be modified
672 logger.Debugw(ctx, "UniTp modify path value", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
673 oo.SOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID] = aPathString
674 }
675 return true
676 }
677 //entry already exists
678 if aPathString == "" {
679 //no active TechProfile
680 logger.Debugw(ctx, "UniTp path has already been removed - no AniSide config to be removed", log.Fields{
681 "device-id": oo.deviceID, "uniID": aUniID})
682 } else {
683 //the given TechProfile already exists and is assumed to be active - update devReason as if the config has been done here
684 //was needed e.g. in voltha POD Tests:Validate authentication on a disabled ONU
685 // (as here the TechProfile has not been removed with the disable-device before the new enable-device)
686 logger.Debugw(ctx, "UniTp path already exists - TechProfile supposed to be active", log.Fields{
687 "device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
688 //no deviceReason update (DeviceProcStatusUpdate) here to ensure 'omci_flows_pushed' state within disable/enable procedure of ATT scenario
689 // (during which the flows are removed/re-assigned but the techProf is left active)
690 //and as the TechProfile is regarded as active we have to verify, if some flow configuration still waits on it
691 // (should not be the case, but should not harm or be more robust ...)
692 // and to be sure, that for some reason the corresponding TpDelete was lost somewhere in history
693 // we also reset a possibly outstanding delete request - repeated TpConfig is regarded as valid for waiting flow config
694 if oo.pOnuTP != nil {
695 oo.pOnuTP.SetProfileToDelete(aUniID, aTpID, false)
696 }
697 go oo.baseDeviceHandler.VerifyVlanConfigRequest(ctx, aUniID, aTpID)
698 }
699 return false //indicate 'no change' - nothing more to do, TechProf inter-adapter message is return with success anyway here
700 }
701 }
702 //no entry exists for uniId
703
704 if aPathString == "" {
705 //delete request in non-existing state , accept as no change
706 logger.Debugw(ctx, "UniTp path already removed", log.Fields{"device-id": oo.deviceID, "uniID": aUniID})
707 return false
708 }
709 //new entry to be created
710 logger.Debugw(ctx, "New UniTp path set", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
711 perSubTpPathMap := make(map[uint8]string)
712 perSubTpPathMap[aTpID] = aPathString
713 oo.SOnuPersistentData.PersUniConfig =
714 append(oo.SOnuPersistentData.PersUniConfig, uniPersConfig{PersUniID: aUniID, PersTpPathMap: perSubTpPathMap, PersFlowParams: make([]cmn.UniVlanFlowParams, 0)})
715 return true
716}
717
718// UpdateOnuUniFlowConfig - TODO: add comment
719func (oo *OnuDeviceEntry) UpdateOnuUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]cmn.UniVlanFlowParams) {
720
721 oo.MutexPersOnuConfig.Lock()
722 defer oo.MutexPersOnuConfig.Unlock()
723
724 for k, v := range oo.SOnuPersistentData.PersUniConfig {
725 if v.PersUniID == aUniID {
726 oo.SOnuPersistentData.PersUniConfig[k].PersFlowParams = make([]cmn.UniVlanFlowParams, len(*aUniVlanFlowParams))
727 copy(oo.SOnuPersistentData.PersUniConfig[k].PersFlowParams, *aUniVlanFlowParams)
728 return
729 }
730 }
731 //flow update was faster than tp-config - create PersUniConfig-entry
732 //TODO!!: following activity to 'add' some new uni entry might not be quite correct if this function is called to clear the data
733 // (e.g after flow removal from RemoveUniFlowParams()).
734 // 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
735 // 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
736 // The code is not changed here because of the current release lane, changes might have unexpected secondary effects, perhaps later with more elaborate tests
737 tmpConfig := uniPersConfig{PersUniID: aUniID, PersTpPathMap: make(map[uint8]string), PersFlowParams: make([]cmn.UniVlanFlowParams, len(*aUniVlanFlowParams))}
738 copy(tmpConfig.PersFlowParams, *aUniVlanFlowParams)
739 oo.SOnuPersistentData.PersUniConfig = append(oo.SOnuPersistentData.PersUniConfig, tmpConfig)
740}
741
742func (oo *OnuDeviceEntry) waitForTimeoutOrCompletion(
743 ctx context.Context, aChOnuProcessingStep <-chan uint8, aProcessingStep uint8) bool {
744 select {
745 case <-ctx.Done():
746 logger.Warnw(ctx, "processing not completed in-time!",
747 log.Fields{"device-id": oo.deviceID, "error": ctx.Err()})
748 return false
749 case rxStep := <-aChOnuProcessingStep:
750 if rxStep == aProcessingStep {
751 return true
752 }
753 //all other values are not accepted - including 0 for error indication
754 logger.Warnw(ctx, "Invalid processing step received: abort!",
755 log.Fields{"device-id": oo.deviceID,
756 "wantedStep": aProcessingStep, "haveStep": rxStep})
757 return false
758 }
759}
760
761// ResetKvProcessingErrorIndication - TODO: add comment
762func (oo *OnuDeviceEntry) ResetKvProcessingErrorIndication() {
763 oo.mutexOnuKVStoreProcResult.Lock()
764 oo.onuKVStoreProcResult = nil
765 oo.mutexOnuKVStoreProcResult.Unlock()
766}
767
768// GetKvProcessingErrorIndication - TODO: add comment
769func (oo *OnuDeviceEntry) GetKvProcessingErrorIndication() error {
770 oo.mutexOnuKVStoreProcResult.RLock()
771 value := oo.onuKVStoreProcResult
772 oo.mutexOnuKVStoreProcResult.RUnlock()
773 return value
774}
775
776func (oo *OnuDeviceEntry) setKvProcessingErrorIndication(value error) {
777 oo.mutexOnuKVStoreProcResult.Lock()
778 oo.onuKVStoreProcResult = value
779 oo.mutexOnuKVStoreProcResult.Unlock()
780}
781
782// IncrementMibDataSync - TODO: add comment
783func (oo *OnuDeviceEntry) IncrementMibDataSync(ctx context.Context) {
784 oo.MutexPersOnuConfig.Lock()
785 defer oo.MutexPersOnuConfig.Unlock()
786 if oo.SOnuPersistentData.PersMibDataSyncAdpt < 255 {
787 oo.SOnuPersistentData.PersMibDataSyncAdpt++
788 } else {
789 // per G.984 and G.988 overflow starts over at 1 given 0 is reserved for reset
790 oo.SOnuPersistentData.PersMibDataSyncAdpt = 1
791 }
792 logger.Debugf(ctx, "mibDataSync updated - mds: %d - device-id: %s", oo.SOnuPersistentData.PersMibDataSyncAdpt, oo.deviceID)
793}
794
795// ModifySwImageInactiveVersion - updates the inactive SW image version stored
796func (oo *OnuDeviceEntry) ModifySwImageInactiveVersion(ctx context.Context, aImageVersion string) {
797 oo.mutexOnuSwImageIndications.Lock()
798 defer oo.mutexOnuSwImageIndications.Unlock()
799 logger.Debugw(ctx, "software-image set inactive version", log.Fields{
800 "device-id": oo.deviceID, "version": aImageVersion})
801 oo.onuSwImageIndications.InActiveEntityEntry.Version = aImageVersion
802 //inactive SW version is not part of persistency data (yet) - no need to update that
803}
804
805// ModifySwImageActiveCommit - updates the active SW commit flag stored
806func (oo *OnuDeviceEntry) ModifySwImageActiveCommit(ctx context.Context, aCommitted uint8) {
807 oo.mutexOnuSwImageIndications.Lock()
808 defer oo.mutexOnuSwImageIndications.Unlock()
809 logger.Debugw(ctx, "software-image set active entity commit flag", log.Fields{
810 "device-id": oo.deviceID, "committed": aCommitted})
811 oo.onuSwImageIndications.ActiveEntityEntry.IsCommitted = aCommitted
812 //commit flag is not part of persistency data (yet) - no need to update that
813}
814
815// GetActiveImageVersion - returns the active SW image version stored
816func (oo *OnuDeviceEntry) GetActiveImageVersion(ctx context.Context) string {
817 oo.mutexOnuSwImageIndications.RLock()
818 if oo.onuSwImageIndications.ActiveEntityEntry.Valid {
819 value := oo.onuSwImageIndications.ActiveEntityEntry.Version
820 oo.mutexOnuSwImageIndications.RUnlock()
821 return value
822 }
823 oo.mutexOnuSwImageIndications.RUnlock()
824 logger.Debugw(ctx, "Active Image is not valid", log.Fields{"device-id": oo.deviceID})
825 return ""
826}
827
828// GetInactiveImageVersion - TODO: add comment
829func (oo *OnuDeviceEntry) GetInactiveImageVersion(ctx context.Context) string {
830 oo.mutexOnuSwImageIndications.RLock()
831 if oo.onuSwImageIndications.InActiveEntityEntry.Valid {
832 value := oo.onuSwImageIndications.InActiveEntityEntry.Version
833 oo.mutexOnuSwImageIndications.RUnlock()
834 return value
835 }
836 oo.mutexOnuSwImageIndications.RUnlock()
837 logger.Debugw(ctx, "Inactive Image is not valid", log.Fields{"device-id": oo.deviceID})
838 return ""
839}
840
841func (oo *OnuDeviceEntry) buildMibTemplatePath() string {
842 oo.MutexPersOnuConfig.RLock()
843 defer oo.MutexPersOnuConfig.RUnlock()
844 return fmt.Sprintf(cSuffixMibTemplateKvStore, oo.SOnuPersistentData.PersVendorID, oo.SOnuPersistentData.PersEquipmentID, oo.SOnuPersistentData.PersActiveSwVersion)
845}
846
847// AllocateFreeTcont - TODO: add comment
848func (oo *OnuDeviceEntry) AllocateFreeTcont(ctx context.Context, allocID uint16) (uint16, bool, error) {
849 logger.Debugw(ctx, "allocate-free-tcont", log.Fields{"device-id": oo.deviceID, "allocID": allocID,
850 "allocated-instances": oo.SOnuPersistentData.PersTcontMap})
851
mpagenko2c3f6c52021-11-23 11:22:10 +0000852 oo.MutexPersOnuConfig.Lock()
853 defer oo.MutexPersOnuConfig.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000854 if entityID, ok := oo.SOnuPersistentData.PersTcontMap[allocID]; ok {
855 //tcont already allocated before, return the used instance-id
856 return entityID, true, nil
857 }
858 //First allocation of tcont. Find a free instance
859 if tcontInstKeys := oo.pOnuDB.GetSortedInstKeys(ctx, me.TContClassID); len(tcontInstKeys) > 0 {
860 logger.Debugw(ctx, "allocate-free-tcont-db-keys", log.Fields{"device-id": oo.deviceID, "keys": tcontInstKeys})
861 for _, instID := range tcontInstKeys {
862 instExist := false
863 //If this instance exist in map, it means it is not empty. It is allocated before
864 for _, v := range oo.SOnuPersistentData.PersTcontMap {
865 if v == instID {
866 instExist = true
867 break
868 }
869 }
870 if !instExist {
871 oo.SOnuPersistentData.PersTcontMap[allocID] = instID
872 return instID, false, nil
873 }
874 }
875 }
876 return 0, false, fmt.Errorf(fmt.Sprintf("no-free-tcont-left-for-device-%s", oo.deviceID))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000877}
878
879// FreeTcont - TODO: add comment
880func (oo *OnuDeviceEntry) FreeTcont(ctx context.Context, allocID uint16) {
881 logger.Debugw(ctx, "free-tcont", log.Fields{"device-id": oo.deviceID, "alloc": allocID})
mpagenko2c3f6c52021-11-23 11:22:10 +0000882 oo.MutexPersOnuConfig.Lock()
883 defer oo.MutexPersOnuConfig.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000884 delete(oo.SOnuPersistentData.PersTcontMap, allocID)
885}
886
887// GetDevOmciCC - TODO: add comment
888func (oo *OnuDeviceEntry) GetDevOmciCC() *cmn.OmciCC {
889 return oo.PDevOmciCC
890}
891
892// GetOnuDB - TODO: add comment
893func (oo *OnuDeviceEntry) GetOnuDB() *devdb.OnuDeviceDB {
894 return oo.pOnuDB
895}
896
897// GetPersSerialNumber - TODO: add comment
898func (oo *OnuDeviceEntry) GetPersSerialNumber() string {
mpagenko2c3f6c52021-11-23 11:22:10 +0000899 oo.MutexPersOnuConfig.RLock()
900 defer oo.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000901 value := oo.SOnuPersistentData.PersSerialNumber
902 return value
903}
904
905// GetPersVendorID - TODO: add comment
906func (oo *OnuDeviceEntry) GetPersVendorID() string {
mpagenko2c3f6c52021-11-23 11:22:10 +0000907 oo.MutexPersOnuConfig.RLock()
908 defer oo.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000909 value := oo.SOnuPersistentData.PersVendorID
910 return value
911}
912
913// GetPersEquipmentID - TODO: add comment
914func (oo *OnuDeviceEntry) GetPersEquipmentID() string {
mpagenko2c3f6c52021-11-23 11:22:10 +0000915 oo.MutexPersOnuConfig.RLock()
916 defer oo.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000917 value := oo.SOnuPersistentData.PersEquipmentID
918 return value
919}
920
921// GetMibUploadFsmCommChan - TODO: add comment
922func (oo *OnuDeviceEntry) GetMibUploadFsmCommChan() chan cmn.Message {
923 return oo.PMibUploadFsm.CommChan
924}
925
926// GetMibDownloadFsmCommChan - TODO: add comment
927func (oo *OnuDeviceEntry) GetMibDownloadFsmCommChan() chan cmn.Message {
928 return oo.PMibDownloadFsm.CommChan
929}
930
931// GetOmciRebootMsgRevChan - TODO: add comment
932func (oo *OnuDeviceEntry) GetOmciRebootMsgRevChan() chan cmn.Message {
933 return oo.omciRebootMessageReceivedChannel
934}
935
936// LockMutexOnuSwImageIndications - TODO: add comment
937func (oo *OnuDeviceEntry) LockMutexOnuSwImageIndications() {
938 oo.mutexOnuSwImageIndications.Lock()
939}
940
941// UnlockMutexOnuSwImageIndications - TODO: add comment
942func (oo *OnuDeviceEntry) UnlockMutexOnuSwImageIndications() {
943 oo.mutexOnuSwImageIndications.Unlock()
944}
945
946// GetOnuSwImageIndications - TODO: add comment
947func (oo *OnuDeviceEntry) GetOnuSwImageIndications() cmn.SswImageIndications {
948 return oo.onuSwImageIndications
949}
950
951// SetOnuSwImageIndications - TODO: add comment
952func (oo *OnuDeviceEntry) SetOnuSwImageIndications(value cmn.SswImageIndications) {
953 oo.onuSwImageIndications = value
954}
955
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000956// GetPersActiveSwVersion - TODO: add comment
957func (oo *OnuDeviceEntry) GetPersActiveSwVersion() string {
mpagenko2c3f6c52021-11-23 11:22:10 +0000958 oo.MutexPersOnuConfig.RLock()
959 defer oo.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000960 return oo.SOnuPersistentData.PersActiveSwVersion
961}
962
963// SetPersActiveSwVersion - TODO: add comment
964func (oo *OnuDeviceEntry) SetPersActiveSwVersion(value string) {
mpagenko2c3f6c52021-11-23 11:22:10 +0000965 oo.MutexPersOnuConfig.Lock()
966 defer oo.MutexPersOnuConfig.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000967 oo.SOnuPersistentData.PersActiveSwVersion = value
968}
969
mpagenko101ac942021-11-16 15:01:29 +0000970// setReconcilingFlows - TODO: add comment
971func (oo *OnuDeviceEntry) setReconcilingFlows(value bool) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000972 oo.mutexReconcilingFlowsFlag.Lock()
973 oo.reconcilingFlows = value
974 oo.mutexReconcilingFlowsFlag.Unlock()
975}
976
mpagenko101ac942021-11-16 15:01:29 +0000977// SendChReconcilingFlowsFinished - TODO: add comment
978func (oo *OnuDeviceEntry) SendChReconcilingFlowsFinished(value bool) {
979 if oo != nil { //if the object still exists (might have been already deleted in background)
980 //use asynchronous channel sending to avoid stucking on non-waiting receiver
981 select {
982 case oo.chReconcilingFlowsFinished <- value:
983 default:
984 }
985 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000986}
987
mpagenko101ac942021-11-16 15:01:29 +0000988// isReconcilingFlows - TODO: add comment
989func (oo *OnuDeviceEntry) isReconcilingFlows() bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000990 oo.mutexReconcilingFlowsFlag.RLock()
991 value := oo.reconcilingFlows
992 oo.mutexReconcilingFlowsFlag.RUnlock()
993 return value
994}