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