blob: 81899a179805d26268efed05e6f06f6bbe507f7f [file] [log] [blame]
Holger Hildebrandtfa074992020-03-27 15:42:06 +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
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000017//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
Holger Hildebrandtfa074992020-03-27 15:42:06 +000019
20import (
21 "context"
Holger Hildebrandt47555e72020-09-21 11:07:24 +000022 "encoding/json"
Holger Hildebrandtccd390c2020-05-29 13:49:04 +000023 "errors"
Holger Hildebrandt47555e72020-09-21 11:07:24 +000024 "fmt"
25 "sync"
Holger Hildebrandt2ff21f12020-08-13 14:38:02 +000026 "time"
27
ozgecanetsiae11479f2020-07-06 09:44:47 +030028 "github.com/opencord/omci-lib-go"
29 me "github.com/opencord/omci-lib-go/generated"
Holger Hildebrandtccd390c2020-05-29 13:49:04 +000030
Holger Hildebrandtfa074992020-03-27 15:42:06 +000031 //"sync"
32 //"time"
33
34 "github.com/looplab/fsm"
dbainbri4d3a0dc2020-12-02 00:33:42 +000035 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/adapterif"
36 "github.com/opencord/voltha-lib-go/v4/pkg/db"
37 "github.com/opencord/voltha-lib-go/v4/pkg/db/kvstore"
Holger Hildebrandtfa074992020-03-27 15:42:06 +000038
dbainbri4d3a0dc2020-12-02 00:33:42 +000039 //"github.com/opencord/voltha-lib-go/v4/pkg/kafka"
40 "github.com/opencord/voltha-lib-go/v4/pkg/log"
41 //ic "github.com/opencord/voltha-protos/v4/go/inter_container"
42 //"github.com/opencord/voltha-protos/v4/go/openflow_13"
43 //"github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandtfa074992020-03-27 15:42:06 +000044)
45
Holger Hildebrandtccd390c2020-05-29 13:49:04 +000046const (
mpagenko1cc3cb42020-07-27 15:24:38 +000047 // events of MibUpload FSM
48 ulEvStart = "ulEvStart"
49 ulEvResetMib = "ulEvResetMib"
50 ulEvGetVendorAndSerial = "ulEvGetVendorAndSerial"
Himani Chawla4d908332020-08-31 12:30:20 +053051 ulEvGetEquipmentID = "ulEvGetEquipmentId"
mpagenko1cc3cb42020-07-27 15:24:38 +000052 ulEvGetFirstSwVersion = "ulEvGetFirstSwVersion"
53 ulEvGetSecondSwVersion = "ulEvGetSecondSwVersion"
54 ulEvGetMacAddress = "ulEvGetMacAddress"
55 ulEvGetMibTemplate = "ulEvGetMibTemplate"
56 ulEvUploadMib = "ulEvUploadMib"
57 ulEvExamineMds = "ulEvExamineMds"
58 ulEvSuccess = "ulEvSuccess"
59 ulEvMismatch = "ulEvMismatch"
60 ulEvAuditMib = "ulEvAuditMib"
61 ulEvForceResync = "ulEvForceResync"
62 ulEvDiffsFound = "ulEvDiffsFound"
63 ulEvTimeout = "ulEvTimeout"
64 ulEvStop = "ulEvStop"
65)
66const (
67 // states of MibUpload FSM
68 ulStDisabled = "ulStDisabled"
69 ulStStarting = "ulStStarting"
70 ulStResettingMib = "ulStResettingMib"
71 ulStGettingVendorAndSerial = "ulStGettingVendorAndSerial"
Himani Chawla4d908332020-08-31 12:30:20 +053072 ulStGettingEquipmentID = "ulStGettingEquipmentID"
mpagenko1cc3cb42020-07-27 15:24:38 +000073 ulStGettingFirstSwVersion = "ulStGettingFirstSwVersion"
74 ulStGettingSecondSwVersion = "ulStGettingSecondSwVersion"
75 ulStGettingMacAddress = "ulStGettingMacAddress"
76 ulStGettingMibTemplate = "ulStGettingMibTemplate"
77 ulStUploading = "ulStUploading"
Holger Hildebrandt10d98192021-01-27 15:29:31 +000078 ulStUploadDone = "ulStUploadDone"
mpagenko1cc3cb42020-07-27 15:24:38 +000079 ulStInSync = "ulStInSync"
80 ulStExaminingMds = "ulStExaminingMds"
81 ulStResynchronizing = "ulStResynchronizing"
82 ulStAuditing = "ulStAuditing"
Holger Hildebrandt10d98192021-01-27 15:29:31 +000083 ulStReAuditing = "ulStReAuditing"
mpagenko1cc3cb42020-07-27 15:24:38 +000084 ulStOutOfSync = "ulStOutOfSync"
85)
Holger Hildebrandt10d98192021-01-27 15:29:31 +000086const cMibUlFsmIdleState = ulStInSync
mpagenko1cc3cb42020-07-27 15:24:38 +000087
88const (
89 // events of MibDownload FSM
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)
100const (
101 // states of MibDownload FSM
102 dlStDisabled = "dlStDisabled"
103 dlStStarting = "dlStStarting"
104 dlStCreatingGal = "dlStCreatingGal"
105 dlStSettingOnu2g = "dlStSettingOnu2g"
106 dlStBridgeInit = "dlStBridgeInit"
107 dlStDownloaded = "dlStDownloaded"
108 dlStResetting = "dlStResetting"
109)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000110const cMibDlFsmIdleState = dlStDisabled
mpagenko1cc3cb42020-07-27 15:24:38 +0000111
112const (
Matteo Scandolof1f39a72020-11-24 12:08:11 -0800113 // NOTE that this hardcoded to service/voltha as the MIB template is shared across stacks
Holger Hildebrandt2ff21f12020-08-13 14:38:02 +0000114 cBasePathMibTemplateKvStore = "service/voltha/omci_mibs/go_templates"
mpagenkoaf801632020-07-03 10:00:42 +0000115 cSuffixMibTemplateKvStore = "%s/%s/%s"
Matteo Scandolof1f39a72020-11-24 12:08:11 -0800116 cBasePathOnuKVStore = "%s/openonu"
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000117)
118
Himani Chawla6d2ae152020-09-02 13:11:20 +0530119// OnuDeviceEvent - event of interest to Device Adapters and OpenOMCI State Machines
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000120type OnuDeviceEvent int
121
122const (
123 // Events of interest to Device Adapters and OpenOMCI State Machines
Himani Chawla6d2ae152020-09-02 13:11:20 +0530124
125 // DeviceStatusInit - default start state
mpagenkofc4f56e2020-11-04 17:17:49 +0000126 DeviceStatusInit OnuDeviceEvent = iota
Himani Chawla6d2ae152020-09-02 13:11:20 +0530127 // MibDatabaseSync - MIB database sync (upload done)
mpagenkofc4f56e2020-11-04 17:17:49 +0000128 MibDatabaseSync
Himani Chawla6d2ae152020-09-02 13:11:20 +0530129 // OmciCapabilitiesDone - OMCI ME and message type capabilities known
mpagenkofc4f56e2020-11-04 17:17:49 +0000130 OmciCapabilitiesDone
Himani Chawla6d2ae152020-09-02 13:11:20 +0530131 // MibDownloadDone - // MIB download done
mpagenkofc4f56e2020-11-04 17:17:49 +0000132 MibDownloadDone
Himani Chawla6d2ae152020-09-02 13:11:20 +0530133 // UniLockStateDone - Uni ports admin set to lock
mpagenkofc4f56e2020-11-04 17:17:49 +0000134 UniLockStateDone
Himani Chawla6d2ae152020-09-02 13:11:20 +0530135 // UniUnlockStateDone - Uni ports admin set to unlock
mpagenkofc4f56e2020-11-04 17:17:49 +0000136 UniUnlockStateDone
mpagenko900ee4b2020-10-12 11:56:34 +0000137 // UniDisableStateDone - Uni ports admin set to lock based on device disable
mpagenkofc4f56e2020-11-04 17:17:49 +0000138 UniDisableStateDone
mpagenko900ee4b2020-10-12 11:56:34 +0000139 // UniEnableStateDone - Uni ports admin set to unlock based on device re-enable
mpagenkofc4f56e2020-11-04 17:17:49 +0000140 UniEnableStateDone
Himani Chawla6d2ae152020-09-02 13:11:20 +0530141 // PortLinkUp - Port link state change
mpagenkofc4f56e2020-11-04 17:17:49 +0000142 PortLinkUp
Himani Chawla6d2ae152020-09-02 13:11:20 +0530143 // PortLinkDw - Port link state change
mpagenkofc4f56e2020-11-04 17:17:49 +0000144 PortLinkDw
Himani Chawla6d2ae152020-09-02 13:11:20 +0530145 // OmciAniConfigDone - AniSide config according to TechProfile done
mpagenkofc4f56e2020-11-04 17:17:49 +0000146 OmciAniConfigDone
147 // OmciAniResourceRemoved - AniSide TechProfile related resource (Gem/TCont) removed
148 OmciAniResourceRemoved // needs to be the successor of OmciAniConfigDone!
149 // OmciVlanFilterAddDone - Omci Vlan config done according to flow-add
150 OmciVlanFilterAddDone
151 // OmciVlanFilterRemDone - Omci Vlan config done according to flow-remove
152 OmciVlanFilterRemDone // needs to be the successor of OmciVlanFilterAddDone!
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000153 // Add other events here as needed (alarms separate???)
154)
155
156type activityDescr struct {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000157 databaseClass func(context.Context) error
Himani Chawla4d908332020-08-31 12:30:20 +0530158 //advertiseEvents bool
Holger Hildebrandte3677f12021-02-05 14:50:56 +0000159 auditInterval time.Duration
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000160 //tasks map[string]func() error
161}
Himani Chawla6d2ae152020-09-02 13:11:20 +0530162
163// OmciDeviceFsms - FSM event mapping to database class and time to wait between audits
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000164type OmciDeviceFsms map[string]activityDescr
165
Himani Chawla6d2ae152020-09-02 13:11:20 +0530166// AdapterFsm - Adapter FSM details including channel, event and device
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000167type AdapterFsm struct {
168 fsmName string
169 deviceID string
170 commChan chan Message
171 pFsm *fsm.FSM
172}
173
Himani Chawla6d2ae152020-09-02 13:11:20 +0530174//NewAdapterFsm - FSM details including event, device and channel.
175func NewAdapterFsm(aName string, aDeviceID string, aCommChannel chan Message) *AdapterFsm {
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000176 aFsm := &AdapterFsm{
Himani Chawla6d2ae152020-09-02 13:11:20 +0530177 fsmName: aName,
178 deviceID: aDeviceID,
179 commChan: aCommChannel,
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000180 }
181 return aFsm
182}
183
184//Start starts (logs) the omci agent
dbainbri4d3a0dc2020-12-02 00:33:42 +0000185func (oo *AdapterFsm) logFsmStateChange(ctx context.Context, e *fsm.Event) {
186 logger.Debugw(ctx, "FSM state change", log.Fields{"device-id": oo.deviceID, "FSM name": oo.fsmName,
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000187 "event name": string(e.Event), "src state": string(e.Src), "dst state": string(e.Dst)})
188}
189
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000190//OntDeviceEntry structure holds information about the attached FSM'as and their communication
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000191
192const (
Himani Chawla6d2ae152020-09-02 13:11:20 +0530193 firstSwImageMeID = 0
194 secondSwImageMeID = 1
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000195)
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +0000196const onuDataMeID = 0
Himani Chawla6d2ae152020-09-02 13:11:20 +0530197const onugMeID = 0
198const onu2gMeID = 0
199const ipHostConfigDataMeID = 1
200const onugSerialNumberLen = 8
201const omciMacAddressLen = 6
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000202
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000203const cEmptyMacAddrString = "000000000000"
204const cEmptySerialNumberString = "0000000000000000"
205
Himani Chawla6d2ae152020-09-02 13:11:20 +0530206type swImages struct {
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000207 version string
208 isActive uint8
209}
210
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000211type uniPersConfig struct {
212 PersUniID uint8 `json:"uni_id"`
Girish Gowdra041dcb32020-11-16 16:54:30 -0800213 PersTpPathMap map[uint8]string `json:"PersTpPathMap"` // tp-id to tp-path map
214 PersFlowParams []uniVlanFlowParams `json:"flow_params"` //as defined in omci_ani_config.go
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000215}
216
217type onuPersistentData struct {
Holger Hildebrandte3677f12021-02-05 14:50:56 +0000218 PersOnuID uint32 `json:"onu_id"`
219 PersIntfID uint32 `json:"intf_id"`
220 PersSnr string `json:"serial_number"`
221 PersAdminState string `json:"admin_state"`
222 PersOperState string `json:"oper_state"`
223 PersUniUnlockDone bool `json:"uni_unlock_done"`
224 PersUniDisableDone bool `json:"uni_disable_done"`
225 PersMibAuditInterval time.Duration `json:"mib_audit_interval"`
226 PersMibLastDbSync uint32 `json:"mib_last_db_sync"`
227 PersMibDataSyncAdpt uint8 `json:"mib_data_sync_adpt"`
228 PersUniConfig []uniPersConfig `json:"uni_config"`
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000229}
230
Himani Chawla6d2ae152020-09-02 13:11:20 +0530231// OnuDeviceEntry - ONU device info and FSM events.
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000232type OnuDeviceEntry struct {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000233 deviceID string
234 baseDeviceHandler *deviceHandler
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000235 pOpenOnuAc *OpenONUAC
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000236 coreProxy adapterif.CoreProxy
237 adapterProxy adapterif.AdapterProxy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000238 PDevOmciCC *omciCC
239 pOnuDB *onuDeviceDB
240 mibTemplateKVStore *db.Backend
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000241 persUniConfigMutex sync.RWMutex
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000242 sOnuPersistentData onuPersistentData
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000243 mibTemplatePath string
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000244 onuKVStoreMutex sync.RWMutex
245 onuKVStore *db.Backend
246 onuKVStorePath string
247 onuKVStoreprocResult error //error indication of processing
248 chOnuKvProcessingStep chan uint8
249 vendorID string
250 serialNumber string
251 equipmentID string
252 swImages [secondSwImageMeID + 1]swImages
253 activeSwVersion string
254 macAddress string
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000255 //lockDeviceEntries sync.RWMutex
dbainbri4d3a0dc2020-12-02 00:33:42 +0000256 mibDbClass func(context.Context) error
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000257 supportedFsms OmciDeviceFsms
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000258 devState OnuDeviceEvent
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +0000259 // Audit and MDS
Holger Hildebrandte3677f12021-02-05 14:50:56 +0000260 mibAuditInterval time.Duration
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000261 // TODO: periodical mib resync will be implemented with story VOL-3792
262 //mibNextDbResync uint32
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000263
264 // for mibUpload
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000265 pMibUploadFsm *AdapterFsm //could be handled dynamically and more general as pAdapterFsm - perhaps later
266 // for mibDownload
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000267 pMibDownloadFsm *AdapterFsm //could be handled dynamically and more general as pAdapterFsm - perhaps later
268 //remark: general usage of pAdapterFsm would require generalization of commChan usage and internal event setting
269 // within the FSM event procedures
ozgecanetsiae11479f2020-07-06 09:44:47 +0300270 omciMessageReceived chan bool //seperate channel needed by DownloadFsm
271 omciRebootMessageReceivedChannel chan Message // channel needed by Reboot request
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000272}
273
Himani Chawla6d2ae152020-09-02 13:11:20 +0530274//newOnuDeviceEntry returns a new instance of a OnuDeviceEntry
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000275//mib_db (as well as not inluded alarm_db not really used in this code? VERIFY!!)
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000276func newOnuDeviceEntry(ctx context.Context, dh *deviceHandler) *OnuDeviceEntry {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000277 logger.Debugw(ctx, "init-onuDeviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000278 var onuDeviceEntry OnuDeviceEntry
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000279 onuDeviceEntry.deviceID = dh.deviceID
280 onuDeviceEntry.baseDeviceHandler = dh
281 onuDeviceEntry.pOpenOnuAc = dh.pOpenOnuAc
282 onuDeviceEntry.coreProxy = dh.coreProxy
283 onuDeviceEntry.adapterProxy = dh.AdapterProxy
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000284 onuDeviceEntry.devState = DeviceStatusInit
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000285 onuDeviceEntry.sOnuPersistentData.PersUniConfig = make([]uniPersConfig, 0)
286 onuDeviceEntry.chOnuKvProcessingStep = make(chan uint8)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300287 onuDeviceEntry.omciRebootMessageReceivedChannel = make(chan Message, 2048)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000288 //openomciagent.lockDeviceHandlersMap = sync.RWMutex{}
289 //OMCI related databases are on a per-agent basis. State machines and tasks
290 //are per ONU Vendor
291 //
292 // MIB Synchronization Database - possible overloading from arguments
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000293 if dh.pOpenOnuAc.pSupportedFsms != nil {
294 onuDeviceEntry.supportedFsms = *dh.pOpenOnuAc.pSupportedFsms
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000295 } else {
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000296 // This branch is currently not used and is for potential future usage of alternative MIB Sync FSMs only!
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000297 //var mibSyncFsm = NewMibSynchronizer()
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000298 // use some internal defaults, if not defined from outside
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000299 onuDeviceEntry.supportedFsms = OmciDeviceFsms{
300 "mib-synchronizer": {
301 //mibSyncFsm, // Implements the MIB synchronization state machine
Himani Chawla6d2ae152020-09-02 13:11:20 +0530302 onuDeviceEntry.mibDbVolatileDict, // Implements volatile ME MIB database
Himani Chawla4d908332020-08-31 12:30:20 +0530303 //true, // Advertise events on OpenOMCI event bus
Holger Hildebrandte3677f12021-02-05 14:50:56 +0000304 dh.pOpenOnuAc.mibAuditInterval, // Time to wait between MIB audits. 0 to disable audits.
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000305 // map[string]func() error{
306 // "mib-upload": onuDeviceEntry.MibUploadTask,
307 // "mib-template": onuDeviceEntry.MibTemplateTask,
308 // "get-mds": onuDeviceEntry.GetMdsTask,
309 // "mib-audit": onuDeviceEntry.GetMdsTask,
310 // "mib-resync": onuDeviceEntry.MibResyncTask,
311 // "mib-reconcile": onuDeviceEntry.MibReconcileTask,
312 // },
313 },
314 }
315 }
316 onuDeviceEntry.mibDbClass = onuDeviceEntry.supportedFsms["mib-synchronizer"].databaseClass
dbainbri4d3a0dc2020-12-02 00:33:42 +0000317 logger.Debug(ctx, "access2mibDbClass")
318 go onuDeviceEntry.mibDbClass(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000319 if !dh.reconciling {
Holger Hildebrandte3677f12021-02-05 14:50:56 +0000320 onuDeviceEntry.mibAuditInterval = onuDeviceEntry.supportedFsms["mib-synchronizer"].auditInterval
321 onuDeviceEntry.sOnuPersistentData.PersMibAuditInterval = onuDeviceEntry.mibAuditInterval
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000322 } else {
Holger Hildebrandte3677f12021-02-05 14:50:56 +0000323 logger.Debugw(ctx, "reconciling - take audit interval from persistent data", log.Fields{"device-id": dh.deviceID})
324 // TODO: This is a preparation for VOL-VOL-3811 to preserve config history in case of
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000325 // vendor- or deviceID-specific configurations via voltctl-commands
Holger Hildebrandte3677f12021-02-05 14:50:56 +0000326 onuDeviceEntry.mibAuditInterval = onuDeviceEntry.sOnuPersistentData.PersMibAuditInterval
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000327 }
Holger Hildebrandte3677f12021-02-05 14:50:56 +0000328 logger.Debugw(ctx, "MibAudit is set to", log.Fields{"Interval": onuDeviceEntry.mibAuditInterval})
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000329 // TODO: periodical mib resync will be implemented with story VOL-3792
330 //onuDeviceEntry.mibNextDbResync = 0
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000331
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000332 // Omci related Mib upload sync state machine
333 mibUploadChan := make(chan Message, 2048)
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000334 onuDeviceEntry.pMibUploadFsm = NewAdapterFsm("MibUpload", dh.deviceID, mibUploadChan)
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000335 onuDeviceEntry.pMibUploadFsm.pFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000336 ulStDisabled,
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000337 fsm.Events{
338
mpagenko1cc3cb42020-07-27 15:24:38 +0000339 {Name: ulEvStart, Src: []string{ulStDisabled}, Dst: ulStStarting},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000340
mpagenko1cc3cb42020-07-27 15:24:38 +0000341 {Name: ulEvResetMib, Src: []string{ulStStarting}, Dst: ulStResettingMib},
342 {Name: ulEvGetVendorAndSerial, Src: []string{ulStResettingMib}, Dst: ulStGettingVendorAndSerial},
Himani Chawla4d908332020-08-31 12:30:20 +0530343 {Name: ulEvGetEquipmentID, Src: []string{ulStGettingVendorAndSerial}, Dst: ulStGettingEquipmentID},
344 {Name: ulEvGetFirstSwVersion, Src: []string{ulStGettingEquipmentID}, Dst: ulStGettingFirstSwVersion},
mpagenko1cc3cb42020-07-27 15:24:38 +0000345 {Name: ulEvGetSecondSwVersion, Src: []string{ulStGettingFirstSwVersion}, Dst: ulStGettingSecondSwVersion},
346 {Name: ulEvGetMacAddress, Src: []string{ulStGettingSecondSwVersion}, Dst: ulStGettingMacAddress},
347 {Name: ulEvGetMibTemplate, Src: []string{ulStGettingMacAddress}, Dst: ulStGettingMibTemplate},
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000348
mpagenko1cc3cb42020-07-27 15:24:38 +0000349 {Name: ulEvUploadMib, Src: []string{ulStGettingMibTemplate}, Dst: ulStUploading},
350 {Name: ulEvExamineMds, Src: []string{ulStStarting}, Dst: ulStExaminingMds},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000351
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000352 {Name: ulEvSuccess, Src: []string{ulStGettingMibTemplate}, Dst: ulStUploadDone},
353 {Name: ulEvSuccess, Src: []string{ulStUploading}, Dst: ulStUploadDone},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000354
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000355 {Name: ulEvSuccess, Src: []string{ulStUploadDone}, Dst: ulStInSync},
mpagenko1cc3cb42020-07-27 15:24:38 +0000356 {Name: ulEvSuccess, Src: []string{ulStExaminingMds}, Dst: ulStInSync},
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +0000357 // TODO: As long as mib-resynchronizing is not implemented, failed MDS-examination triggers
358 // mib-reset and new provisioning at this point
359 //{Name: ulEvMismatch, Src: []string{ulStExaminingMds}, Dst: ulStResynchronizing},
360 {Name: ulEvMismatch, Src: []string{ulStExaminingMds}, Dst: ulStResettingMib},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000361
mpagenko1cc3cb42020-07-27 15:24:38 +0000362 {Name: ulEvAuditMib, Src: []string{ulStInSync}, Dst: ulStAuditing},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000363
mpagenko1cc3cb42020-07-27 15:24:38 +0000364 {Name: ulEvSuccess, Src: []string{ulStOutOfSync}, Dst: ulStInSync},
365 {Name: ulEvAuditMib, Src: []string{ulStOutOfSync}, Dst: ulStAuditing},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000366
mpagenko1cc3cb42020-07-27 15:24:38 +0000367 {Name: ulEvSuccess, Src: []string{ulStAuditing}, Dst: ulStInSync},
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000368 {Name: ulEvMismatch, Src: []string{ulStAuditing}, Dst: ulStReAuditing},
mpagenko1cc3cb42020-07-27 15:24:38 +0000369 {Name: ulEvForceResync, Src: []string{ulStAuditing}, Dst: ulStResynchronizing},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000370
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000371 {Name: ulEvSuccess, Src: []string{ulStReAuditing}, Dst: ulStInSync},
372 {Name: ulEvMismatch, Src: []string{ulStReAuditing}, Dst: ulStResettingMib},
373
mpagenko1cc3cb42020-07-27 15:24:38 +0000374 {Name: ulEvSuccess, Src: []string{ulStResynchronizing}, Dst: ulStInSync},
375 {Name: ulEvDiffsFound, Src: []string{ulStResynchronizing}, Dst: ulStOutOfSync},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000376
Himani Chawla4d908332020-08-31 12:30:20 +0530377 {Name: ulEvTimeout, Src: []string{ulStResettingMib, ulStGettingVendorAndSerial, ulStGettingEquipmentID, ulStGettingFirstSwVersion,
mpagenko1cc3cb42020-07-27 15:24:38 +0000378 ulStGettingSecondSwVersion, ulStGettingMacAddress, ulStGettingMibTemplate, ulStUploading, ulStResynchronizing, ulStExaminingMds,
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000379 ulStUploadDone, ulStInSync, ulStOutOfSync, ulStAuditing, ulStReAuditing}, Dst: ulStStarting},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000380
Himani Chawla4d908332020-08-31 12:30:20 +0530381 {Name: ulEvStop, Src: []string{ulStStarting, ulStResettingMib, ulStGettingVendorAndSerial, ulStGettingEquipmentID, ulStGettingFirstSwVersion,
mpagenko1cc3cb42020-07-27 15:24:38 +0000382 ulStGettingSecondSwVersion, ulStGettingMacAddress, ulStGettingMibTemplate, ulStUploading, ulStResynchronizing, ulStExaminingMds,
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000383 ulStUploadDone, ulStInSync, ulStOutOfSync, ulStAuditing, ulStReAuditing}, Dst: ulStDisabled},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000384 },
385
386 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000387 "enter_state": func(e *fsm.Event) { onuDeviceEntry.pMibUploadFsm.logFsmStateChange(ctx, e) },
388 "enter_" + ulStStarting: func(e *fsm.Event) { onuDeviceEntry.enterStartingState(ctx, e) },
389 "enter_" + ulStResettingMib: func(e *fsm.Event) { onuDeviceEntry.enterResettingMibState(ctx, e) },
390 "enter_" + ulStGettingVendorAndSerial: func(e *fsm.Event) { onuDeviceEntry.enterGettingVendorAndSerialState(ctx, e) },
391 "enter_" + ulStGettingEquipmentID: func(e *fsm.Event) { onuDeviceEntry.enterGettingEquipmentIDState(ctx, e) },
392 "enter_" + ulStGettingFirstSwVersion: func(e *fsm.Event) { onuDeviceEntry.enterGettingFirstSwVersionState(ctx, e) },
393 "enter_" + ulStGettingSecondSwVersion: func(e *fsm.Event) { onuDeviceEntry.enterGettingSecondSwVersionState(ctx, e) },
394 "enter_" + ulStGettingMacAddress: func(e *fsm.Event) { onuDeviceEntry.enterGettingMacAddressState(ctx, e) },
395 "enter_" + ulStGettingMibTemplate: func(e *fsm.Event) { onuDeviceEntry.enterGettingMibTemplate(ctx, e) },
396 "enter_" + ulStUploading: func(e *fsm.Event) { onuDeviceEntry.enterUploadingState(ctx, e) },
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000397 "enter_" + ulStUploadDone: func(e *fsm.Event) { onuDeviceEntry.enterUploadDoneState(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000398 "enter_" + ulStExaminingMds: func(e *fsm.Event) { onuDeviceEntry.enterExaminingMdsState(ctx, e) },
399 "enter_" + ulStResynchronizing: func(e *fsm.Event) { onuDeviceEntry.enterResynchronizingState(ctx, e) },
400 "enter_" + ulStAuditing: func(e *fsm.Event) { onuDeviceEntry.enterAuditingState(ctx, e) },
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000401 "enter_" + ulStReAuditing: func(e *fsm.Event) { onuDeviceEntry.enterReAuditingState(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000402 "enter_" + ulStOutOfSync: func(e *fsm.Event) { onuDeviceEntry.enterOutOfSyncState(ctx, e) },
403 "enter_" + ulStInSync: func(e *fsm.Event) { onuDeviceEntry.enterInSyncState(ctx, e) },
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000404 },
405 )
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000406 // Omci related Mib download state machine
407 mibDownloadChan := make(chan Message, 2048)
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000408 onuDeviceEntry.pMibDownloadFsm = NewAdapterFsm("MibDownload", dh.deviceID, mibDownloadChan)
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000409 onuDeviceEntry.pMibDownloadFsm.pFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000410 dlStDisabled,
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000411 fsm.Events{
412
mpagenko1cc3cb42020-07-27 15:24:38 +0000413 {Name: dlEvStart, Src: []string{dlStDisabled}, Dst: dlStStarting},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000414
mpagenko1cc3cb42020-07-27 15:24:38 +0000415 {Name: dlEvCreateGal, Src: []string{dlStStarting}, Dst: dlStCreatingGal},
416 {Name: dlEvRxGalResp, Src: []string{dlStCreatingGal}, Dst: dlStSettingOnu2g},
417 {Name: dlEvRxOnu2gResp, Src: []string{dlStSettingOnu2g}, Dst: dlStBridgeInit},
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000418 // the bridge state is used for multi ME config for alle UNI related ports
419 // maybe such could be reflected in the state machine as well (port number parametrized)
420 // but that looks not straightforward here - so we keep it simple here for the beginning(?)
mpagenko1cc3cb42020-07-27 15:24:38 +0000421 {Name: dlEvRxBridgeResp, Src: []string{dlStBridgeInit}, Dst: dlStDownloaded},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000422
mpagenko1cc3cb42020-07-27 15:24:38 +0000423 {Name: dlEvTimeoutSimple, Src: []string{dlStCreatingGal, dlStSettingOnu2g}, Dst: dlStStarting},
424 {Name: dlEvTimeoutBridge, Src: []string{dlStBridgeInit}, Dst: dlStStarting},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000425
mpagenko1cc3cb42020-07-27 15:24:38 +0000426 {Name: dlEvReset, Src: []string{dlStStarting, dlStCreatingGal, dlStSettingOnu2g,
427 dlStBridgeInit, dlStDownloaded}, Dst: dlStResetting},
428 // exceptional treatment for all states except dlStResetting
429 {Name: dlEvRestart, Src: []string{dlStStarting, dlStCreatingGal, dlStSettingOnu2g,
430 dlStBridgeInit, dlStDownloaded, dlStResetting}, Dst: dlStDisabled},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000431 },
432
433 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000434 "enter_state": func(e *fsm.Event) { onuDeviceEntry.pMibDownloadFsm.logFsmStateChange(ctx, e) },
435 "enter_" + dlStStarting: func(e *fsm.Event) { onuDeviceEntry.enterDLStartingState(ctx, e) },
436 "enter_" + dlStCreatingGal: func(e *fsm.Event) { onuDeviceEntry.enterCreatingGalState(ctx, e) },
437 "enter_" + dlStSettingOnu2g: func(e *fsm.Event) { onuDeviceEntry.enterSettingOnu2gState(ctx, e) },
438 "enter_" + dlStBridgeInit: func(e *fsm.Event) { onuDeviceEntry.enterBridgeInitState(ctx, e) },
439 "enter_" + dlStDownloaded: func(e *fsm.Event) { onuDeviceEntry.enterDownloadedState(ctx, e) },
440 "enter_" + dlStResetting: func(e *fsm.Event) { onuDeviceEntry.enterResettingState(ctx, e) },
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000441 },
442 )
443 if onuDeviceEntry.pMibDownloadFsm == nil || onuDeviceEntry.pMibDownloadFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000444 logger.Errorw(ctx, "MibDownloadFsm could not be instantiated", log.Fields{"device-id": dh.deviceID})
Andrea Campanella6515c582020-10-05 11:25:00 +0200445 // TODO some specifc error treatment - or waiting for crash ?
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000446 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000447
dbainbri4d3a0dc2020-12-02 00:33:42 +0000448 onuDeviceEntry.mibTemplateKVStore = onuDeviceEntry.baseDeviceHandler.setBackend(ctx, cBasePathMibTemplateKvStore)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000449 if onuDeviceEntry.mibTemplateKVStore == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000450 logger.Errorw(ctx, "Can't access mibTemplateKVStore - no backend connection to service",
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000451 log.Fields{"device-id": dh.deviceID, "service": cBasePathMibTemplateKvStore})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000452 }
453
454 onuDeviceEntry.onuKVStorePath = onuDeviceEntry.deviceID
Matteo Scandolof1f39a72020-11-24 12:08:11 -0800455 baseKvStorePath := fmt.Sprintf(cBasePathOnuKVStore, dh.pOpenOnuAc.cm.Backend.PathPrefix)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000456 onuDeviceEntry.onuKVStore = onuDeviceEntry.baseDeviceHandler.setBackend(ctx, baseKvStorePath)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000457 if onuDeviceEntry.onuKVStore == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000458 logger.Errorw(ctx, "Can't access onuKVStore - no backend connection to service",
Matteo Scandolof1f39a72020-11-24 12:08:11 -0800459 log.Fields{"device-id": dh.deviceID, "service": baseKvStorePath})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000460 }
461
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000462 // Alarm Synchronization Database
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530463
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000464 //self._alarm_db = None
465 //self._alarm_database_cls = support_classes['alarm-synchronizer']['database']
466 return &onuDeviceEntry
467}
468
Himani Chawla6d2ae152020-09-02 13:11:20 +0530469//start starts (logs) the omci agent
470func (oo *OnuDeviceEntry) start(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000471 logger.Debugw(ctx, "OnuDeviceEntry-starting", log.Fields{"for device-id": oo.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000472 if oo.PDevOmciCC == nil {
mpagenko900ee4b2020-10-12 11:56:34 +0000473 oo.PDevOmciCC = newOmciCC(ctx, oo, oo.deviceID, oo.baseDeviceHandler,
474 oo.coreProxy, oo.adapterProxy)
475 if oo.PDevOmciCC == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000476 logger.Errorw(ctx, "Could not create devOmciCc - abort", log.Fields{"for device-id": oo.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +0000477 return fmt.Errorf("could not create devOmciCc %s", oo.deviceID)
478 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000479 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000480 return nil
481}
482
mpagenko900ee4b2020-10-12 11:56:34 +0000483//stop stops/resets the omciCC
484func (oo *OnuDeviceEntry) stop(ctx context.Context, abResetOmciCC bool) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000485 logger.Debugw(ctx, "OnuDeviceEntry-stopping", log.Fields{"for device-id": oo.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +0000486 if abResetOmciCC && (oo.PDevOmciCC != nil) {
487 _ = oo.PDevOmciCC.stop(ctx)
488 }
489 //to allow for all event notifications again when re-using the device and omciCC
490 oo.devState = DeviceStatusInit
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000491 return nil
492}
493
Himani Chawla6d2ae152020-09-02 13:11:20 +0530494func (oo *OnuDeviceEntry) reboot(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000495 logger.Debugw(ctx, "OnuDeviceEntry-rebooting", log.Fields{"for device-id": oo.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +0000496 if oo.PDevOmciCC != nil {
497 if err := oo.PDevOmciCC.sendReboot(ctx, ConstDefaultOmciTimeout, true, oo.omciRebootMessageReceivedChannel); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000498 logger.Errorw(ctx, "onu didn't reboot", log.Fields{"for device-id": oo.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +0000499 return err
500 }
ozgecanetsiae11479f2020-07-06 09:44:47 +0300501 }
ozgecanetsiae11479f2020-07-06 09:44:47 +0300502 return nil
503}
504
dbainbri4d3a0dc2020-12-02 00:33:42 +0000505func (oo *OnuDeviceEntry) waitForRebootResponse(ctx context.Context, responseChannel chan Message) error {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300506 select {
507 case <-time.After(3 * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
dbainbri4d3a0dc2020-12-02 00:33:42 +0000508 logger.Warnw(ctx, "Reboot timeout", log.Fields{"for device-id": oo.deviceID})
Andrea Campanella6515c582020-10-05 11:25:00 +0200509 return fmt.Errorf("rebootTimeout")
ozgecanetsiae11479f2020-07-06 09:44:47 +0300510 case data := <-responseChannel:
511 switch data.Data.(OmciMessage).OmciMsg.MessageType {
512 case omci.RebootResponseType:
513 {
514 msgLayer := (*data.Data.(OmciMessage).OmciPacket).Layer(omci.LayerTypeRebootResponse)
515 if msgLayer == nil {
Andrea Campanella6515c582020-10-05 11:25:00 +0200516 return fmt.Errorf("omci Msg layer could not be detected for RebootResponseType")
ozgecanetsiae11479f2020-07-06 09:44:47 +0300517 }
Andrea Campanellabef4e542020-10-22 11:01:28 +0200518 msgObj, msgOk := msgLayer.(*omci.RebootResponse)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300519 if !msgOk {
Andrea Campanella6515c582020-10-05 11:25:00 +0200520 return fmt.Errorf("omci Msg layer could not be assigned for RebootResponseType %s", oo.deviceID)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300521 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000522 logger.Debugw(ctx, "RebootResponse data", log.Fields{"device-id": oo.deviceID, "data-fields": msgObj})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300523 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000524 logger.Errorw(ctx, "Omci RebootResponse result error", log.Fields{"device-id": oo.deviceID, "Error": msgObj.Result})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300525 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
Andrea Campanellabef4e542020-10-22 11:01:28 +0200526 return fmt.Errorf("omci RebootResponse result error indication %s for device %s",
Andrea Campanella6515c582020-10-05 11:25:00 +0200527 msgObj.Result, oo.deviceID)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300528 }
529 return nil
530 }
531 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000532 logger.Warnw(ctx, "Reboot response message type error", log.Fields{"for device-id": oo.deviceID})
Andrea Campanella6515c582020-10-05 11:25:00 +0200533 return fmt.Errorf("unexpected OmciResponse type received %s", oo.deviceID)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300534 }
535}
536
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000537//Relay the InSync message via Handler to Rw core - Status update
dbainbri4d3a0dc2020-12-02 00:33:42 +0000538func (oo *OnuDeviceEntry) transferSystemEvent(ctx context.Context, devEvent OnuDeviceEvent) {
539 logger.Debugw(ctx, "relaying system-event", log.Fields{"Event": devEvent})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000540 // decouple the handler transfer from further processing here
541 // TODO!!! check if really no synch is required within the system e.g. to ensure following steps ..
Himani Chawla26e555c2020-08-31 12:30:20 +0530542 if devEvent == MibDatabaseSync {
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000543 if oo.devState < MibDatabaseSync { //devState has not been synced yet
544 oo.devState = MibDatabaseSync
dbainbri4d3a0dc2020-12-02 00:33:42 +0000545 go oo.baseDeviceHandler.deviceProcStatusUpdate(ctx, devEvent)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000546 //TODO!!! device control: next step: start MIB capability verification from here ?!!!
547 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000548 logger.Debugw(ctx, "mibinsync-event in some already synced state - ignored", log.Fields{"state": oo.devState})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000549 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530550 } else if devEvent == MibDownloadDone {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000551 if oo.devState < MibDownloadDone { //devState has not been synced yet
552 oo.devState = MibDownloadDone
dbainbri4d3a0dc2020-12-02 00:33:42 +0000553 go oo.baseDeviceHandler.deviceProcStatusUpdate(ctx, devEvent)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000554 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000555 logger.Debugw(ctx, "mibdownloaddone-event was already seen - ignored", log.Fields{"state": oo.devState})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000556 }
557 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000558 logger.Warnw(ctx, "device-event not yet handled", log.Fields{"state": devEvent})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000559 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000560}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000561
562func (oo *OnuDeviceEntry) restoreDataFromOnuKvStore(ctx context.Context) error {
563 if oo.onuKVStore == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000564 logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000565 return fmt.Errorf(fmt.Sprintf("onuKVStore-not-set-abort-%s", oo.deviceID))
566 }
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000567 oo.persUniConfigMutex.Lock()
568 defer oo.persUniConfigMutex.Unlock()
Holger Hildebrandte3677f12021-02-05 14:50:56 +0000569 oo.sOnuPersistentData = onuPersistentData{0, 0, "", "", "", false, false, oo.mibAuditInterval, 0, 0, make([]uniPersConfig, 0)}
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000570 oo.onuKVStoreMutex.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000571 Value, err := oo.onuKVStore.Get(ctx, oo.onuKVStorePath)
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000572 oo.onuKVStoreMutex.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000573 if err == nil {
574 if Value != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000575 logger.Debugw(ctx, "ONU-data read",
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000576 log.Fields{"Key": Value.Key, "device-id": oo.deviceID})
577 tmpBytes, _ := kvstore.ToByte(Value.Value)
578
579 if err = json.Unmarshal(tmpBytes, &oo.sOnuPersistentData); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000580 logger.Errorw(ctx, "unable to unmarshal ONU-data", log.Fields{"error": err, "device-id": oo.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000581 return fmt.Errorf(fmt.Sprintf("unable-to-unmarshal-ONU-data-%s", oo.deviceID))
582 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000583 logger.Debugw(ctx, "ONU-data", log.Fields{"sOnuPersistentData": oo.sOnuPersistentData,
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000584 "device-id": oo.deviceID})
585 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000586 logger.Debugw(ctx, "no ONU-data found", log.Fields{"path": oo.onuKVStorePath, "device-id": oo.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000587 return fmt.Errorf("no-ONU-data-found")
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000588 }
589 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000590 logger.Errorw(ctx, "unable to read from KVstore", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000591 return fmt.Errorf(fmt.Sprintf("unable-to-read-from-KVstore-%s", oo.deviceID))
592 }
593 return nil
594}
595
596func (oo *OnuDeviceEntry) deleteDataFromOnuKvStore(ctx context.Context, wg *sync.WaitGroup) {
597 defer wg.Done()
598
599 if oo.onuKVStore == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000600 logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000601 oo.onuKVStoreprocResult = errors.New("onu-data delete aborted: onuKVStore not set")
602 return
603 }
604 var processingStep uint8 = 1 // used to synchronize the different processing steps with chOnuKvProcessingStep
605 go oo.deletePersistentData(ctx, processingStep)
606 if !oo.waitForTimeoutOrCompletion(ctx, oo.chOnuKvProcessingStep, processingStep) {
607 //timeout or error detected
dbainbri4d3a0dc2020-12-02 00:33:42 +0000608 logger.Debugw(ctx, "ONU-data not deleted - abort", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000609 oo.onuKVStoreprocResult = errors.New("onu-data delete aborted: during kv-access")
610 return
611 }
612}
613
614func (oo *OnuDeviceEntry) deletePersistentData(ctx context.Context, aProcessingStep uint8) {
615
dbainbri4d3a0dc2020-12-02 00:33:42 +0000616 logger.Debugw(ctx, "delete and clear internal persistency data", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000617
618 oo.persUniConfigMutex.Lock()
619 defer oo.persUniConfigMutex.Unlock()
620
Holger Hildebrandte3677f12021-02-05 14:50:56 +0000621 oo.sOnuPersistentData.PersUniConfig = nil //releasing all UniConfig entries to garbage collector
622 oo.sOnuPersistentData = onuPersistentData{0, 0, "", "", "", false, false, oo.mibAuditInterval, 0, 0, make([]uniPersConfig, 0)} //default entry
mpagenko2418ab02020-11-12 12:58:06 +0000623
dbainbri4d3a0dc2020-12-02 00:33:42 +0000624 logger.Debugw(ctx, "delete ONU-data from KVStore", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000625 oo.onuKVStoreMutex.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000626 err := oo.onuKVStore.Delete(ctx, oo.onuKVStorePath)
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000627 oo.onuKVStoreMutex.Unlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000628 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000629 logger.Errorw(ctx, "unable to delete in KVstore", log.Fields{"device-id": oo.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000630 oo.chOnuKvProcessingStep <- 0 //error indication
631 return
632 }
633 oo.chOnuKvProcessingStep <- aProcessingStep //done
634}
635
636func (oo *OnuDeviceEntry) updateOnuKvStore(ctx context.Context, wg *sync.WaitGroup) {
637 defer wg.Done()
638
639 if oo.onuKVStore == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000640 logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000641 oo.onuKVStoreprocResult = errors.New("onu-data update aborted: onuKVStore not set")
642 return
643 }
644 var processingStep uint8 = 1 // used to synchronize the different processing steps with chOnuKvProcessingStep
645 go oo.storeDataInOnuKvStore(ctx, processingStep)
646 if !oo.waitForTimeoutOrCompletion(ctx, oo.chOnuKvProcessingStep, processingStep) {
647 //timeout or error detected
dbainbri4d3a0dc2020-12-02 00:33:42 +0000648 logger.Debugw(ctx, "ONU-data not written - abort", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000649 oo.onuKVStoreprocResult = errors.New("onu-data update aborted: during writing process")
650 return
651 }
652}
653
654func (oo *OnuDeviceEntry) storeDataInOnuKvStore(ctx context.Context, aProcessingStep uint8) {
655
656 //assign values which are not already present when newOnuDeviceEntry() is called
657 oo.sOnuPersistentData.PersOnuID = oo.baseDeviceHandler.pOnuIndication.OnuId
658 oo.sOnuPersistentData.PersIntfID = oo.baseDeviceHandler.pOnuIndication.IntfId
659 oo.sOnuPersistentData.PersSnr = oo.baseDeviceHandler.pOnuOmciDevice.serialNumber
660 //TODO: verify usage of these values during restart UC
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000661 oo.sOnuPersistentData.PersAdminState = oo.baseDeviceHandler.pOnuIndication.AdminState
662 oo.sOnuPersistentData.PersOperState = oo.baseDeviceHandler.pOnuIndication.OperState
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000663
664 oo.persUniConfigMutex.RLock()
665 defer oo.persUniConfigMutex.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000666 logger.Debugw(ctx, "Update ONU-data in KVStore", log.Fields{"device-id": oo.deviceID, "sOnuPersistentData": oo.sOnuPersistentData})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000667
668 Value, err := json.Marshal(oo.sOnuPersistentData)
669 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000670 logger.Errorw(ctx, "unable to marshal ONU-data", log.Fields{"sOnuPersistentData": oo.sOnuPersistentData,
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000671 "device-id": oo.deviceID, "err": err})
672 oo.chOnuKvProcessingStep <- 0 //error indication
673 return
674 }
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000675 oo.onuKVStoreMutex.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000676 err = oo.onuKVStore.Put(ctx, oo.onuKVStorePath, Value)
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000677 oo.onuKVStoreMutex.Unlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000678 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000679 logger.Errorw(ctx, "unable to write ONU-data into KVstore", log.Fields{"device-id": oo.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000680 oo.chOnuKvProcessingStep <- 0 //error indication
681 return
682 }
683 oo.chOnuKvProcessingStep <- aProcessingStep //done
684}
685
dbainbri4d3a0dc2020-12-02 00:33:42 +0000686func (oo *OnuDeviceEntry) updateOnuUniTpPath(ctx context.Context, aUniID uint8, aTpID uint8, aPathString string) bool {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000687 /* within some specific InterAdapter processing request write/read access to data is ensured to be sequentially,
688 as also the complete sequence is ensured to 'run to completion' before some new request is accepted
689 no specific concurrency protection to sOnuPersistentData is required here
690 */
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000691 oo.persUniConfigMutex.Lock()
692 defer oo.persUniConfigMutex.Unlock()
693
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000694 for k, v := range oo.sOnuPersistentData.PersUniConfig {
695 if v.PersUniID == aUniID {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000696 logger.Debugw(ctx, "PersUniConfig-entry already exists", log.Fields{"device-id": oo.deviceID, "uniID": aUniID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800697 existingPath, ok := oo.sOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID]
698 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000699 logger.Debugw(ctx, "tp-does-not-exist--to-be-created-afresh", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "tpID": aTpID, "path": aPathString})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800700 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000701 if existingPath != aPathString {
702 if aPathString == "" {
703 //existing entry to be deleted
dbainbri4d3a0dc2020-12-02 00:33:42 +0000704 logger.Debugw(ctx, "UniTp delete path value", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800705 oo.sOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID] = ""
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000706 } else {
707 //existing entry to be modified
dbainbri4d3a0dc2020-12-02 00:33:42 +0000708 logger.Debugw(ctx, "UniTp modify path value", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800709 oo.sOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID] = aPathString
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000710 }
711 return true
712 }
713 //entry already exists
mpagenkofc4f56e2020-11-04 17:17:49 +0000714 if aPathString == "" {
715 //no active TechProfile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000716 logger.Debugw(ctx, "UniTp path has already been removed - no AniSide config to be removed", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000717 "device-id": oo.deviceID, "uniID": aUniID})
718 // attention 201105: this block is at the moment entered for each of subsequent GemPortDeletes and TContDelete
719 // as the path is already cleared with the first GemPort - this will probably change with the upcoming real
720 // TechProfile removal (still TODO), but anyway the reasonUpdate initiated here should not harm overall behavior
dbainbri4d3a0dc2020-12-02 00:33:42 +0000721 go oo.baseDeviceHandler.deviceProcStatusUpdate(ctx, OmciAniResourceRemoved)
mpagenkofc4f56e2020-11-04 17:17:49 +0000722 // no flow config pending on 'remove' so far
723 } else {
724 //the given TechProfile already exists and is assumed to be active - update devReason as if the config has been done here
725 //was needed e.g. in voltha POD Tests:Validate authentication on a disabled ONU
726 // (as here the TechProfile has not been removed with the disable-device before the new enable-device)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 logger.Debugw(ctx, "UniTp path already exists - TechProfile supposed to be active", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000728 "device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
729 //no deviceReason update (deviceProcStatusUpdate) here to ensure 'omci_flows_pushed' state within disable/enable procedure of ATT scenario
730 // (during which the flows are removed/re-assigned but the techProf is left active)
731 //and as the TechProfile is regarded as active we have to verify, if some flow configuration still waits on it
732 // (should not be the case, but should not harm or be more robust ...)
mpagenko2418ab02020-11-12 12:58:06 +0000733 // and to be sure, that for some reason the corresponding TpDelete was lost somewhere in history
734 // we also reset a possibly outstanding delete request - repeated TpConfig is regarded as valid for waiting flow config
735 if oo.baseDeviceHandler.pOnuTP != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -0800736 oo.baseDeviceHandler.pOnuTP.setProfileToDelete(aUniID, aTpID, false)
mpagenko2418ab02020-11-12 12:58:06 +0000737 }
mpagenko551a4d42020-12-08 18:09:20 +0000738 go oo.baseDeviceHandler.VerifyVlanConfigRequest(ctx, aUniID, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +0000739 }
740 return false //indicate 'no change' - nothing more to do, TechProf inter-adapter message is return with success anyway here
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000741 }
742 }
743 //no entry exists for uniId
744
745 if aPathString == "" {
746 //delete request in non-existing state , accept as no change
dbainbri4d3a0dc2020-12-02 00:33:42 +0000747 logger.Debugw(ctx, "UniTp path already removed", log.Fields{"device-id": oo.deviceID, "uniID": aUniID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000748 return false
749 }
750 //new entry to be created
dbainbri4d3a0dc2020-12-02 00:33:42 +0000751 logger.Debugw(ctx, "New UniTp path set", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800752 perSubTpPathMap := make(map[uint8]string)
753 perSubTpPathMap[aTpID] = aPathString
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000754 oo.sOnuPersistentData.PersUniConfig =
Girish Gowdra041dcb32020-11-16 16:54:30 -0800755 append(oo.sOnuPersistentData.PersUniConfig, uniPersConfig{PersUniID: aUniID, PersTpPathMap: perSubTpPathMap, PersFlowParams: make([]uniVlanFlowParams, 0)})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000756 return true
757}
758
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000759func (oo *OnuDeviceEntry) updateOnuUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) {
760
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000761 oo.persUniConfigMutex.Lock()
762 defer oo.persUniConfigMutex.Unlock()
763
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000764 for k, v := range oo.sOnuPersistentData.PersUniConfig {
765 if v.PersUniID == aUniID {
766 oo.sOnuPersistentData.PersUniConfig[k].PersFlowParams = make([]uniVlanFlowParams, len(*aUniVlanFlowParams))
767 copy(oo.sOnuPersistentData.PersUniConfig[k].PersFlowParams, *aUniVlanFlowParams)
768 return
769 }
770 }
771 //flow update was faster than tp-config - create PersUniConfig-entry
Girish Gowdra041dcb32020-11-16 16:54:30 -0800772 tmpConfig := uniPersConfig{PersUniID: aUniID, PersTpPathMap: make(map[uint8]string), PersFlowParams: make([]uniVlanFlowParams, len(*aUniVlanFlowParams))}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000773 copy(tmpConfig.PersFlowParams, *aUniVlanFlowParams)
774 oo.sOnuPersistentData.PersUniConfig = append(oo.sOnuPersistentData.PersUniConfig, tmpConfig)
775}
776
777func (oo *OnuDeviceEntry) waitForTimeoutOrCompletion(
778 ctx context.Context, aChOnuProcessingStep <-chan uint8, aProcessingStep uint8) bool {
779 select {
780 case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +0000781 logger.Warnw(ctx, "processing not completed in-time!",
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000782 log.Fields{"device-id": oo.deviceID, "error": ctx.Err()})
783 return false
784 case rxStep := <-aChOnuProcessingStep:
785 if rxStep == aProcessingStep {
786 return true
787 }
788 //all other values are not accepted - including 0 for error indication
dbainbri4d3a0dc2020-12-02 00:33:42 +0000789 logger.Warnw(ctx, "Invalid processing step received: abort!",
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000790 log.Fields{"device-id": oo.deviceID,
791 "wantedStep": aProcessingStep, "haveStep": rxStep})
792 return false
793 }
794}
795
796func (oo *OnuDeviceEntry) resetKvProcessingErrorIndication() {
797 oo.onuKVStoreprocResult = nil
798}
799func (oo *OnuDeviceEntry) getKvProcessingErrorIndication() error {
800 return oo.onuKVStoreprocResult
801}
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +0000802func (oo *OnuDeviceEntry) incrementMibDataSync(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000803 if oo.sOnuPersistentData.PersMibDataSyncAdpt < 255 {
804 oo.sOnuPersistentData.PersMibDataSyncAdpt++
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +0000805 } else {
806 // per G.984 and G.988 overflow starts over at 1 given 0 is reserved for reset
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000807 oo.sOnuPersistentData.PersMibDataSyncAdpt = 1
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +0000808 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000809 logger.Debugf(ctx, "mibDataSync updated - mds: %d - device-id: %s", oo.sOnuPersistentData.PersMibDataSyncAdpt, oo.deviceID)
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +0000810}