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