blob: adf630e2efcea408d94c14123f8b18612b11aade [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"
35 "github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
Holger Hildebrandtccd390c2020-05-29 13:49:04 +000036 "github.com/opencord/voltha-lib-go/v3/pkg/db"
Holger Hildebrandt47555e72020-09-21 11:07:24 +000037 "github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore"
Holger Hildebrandtfa074992020-03-27 15:42:06 +000038
39 //"github.com/opencord/voltha-lib-go/v3/pkg/kafka"
40 "github.com/opencord/voltha-lib-go/v3/pkg/log"
41 //ic "github.com/opencord/voltha-protos/v3/go/inter_container"
42 //"github.com/opencord/voltha-protos/v3/go/openflow_13"
43 //"github.com/opencord/voltha-protos/v3/go/voltha"
44)
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"
78 ulStInSync = "ulStInSync"
79 ulStExaminingMds = "ulStExaminingMds"
80 ulStResynchronizing = "ulStResynchronizing"
81 ulStAuditing = "ulStAuditing"
82 ulStOutOfSync = "ulStOutOfSync"
83)
84
85const (
86 // events of MibDownload FSM
87 dlEvStart = "dlEvStart"
88 dlEvCreateGal = "dlEvCreateGal"
89 dlEvRxGalResp = "dlEvRxGalResp"
90 dlEvRxOnu2gResp = "dlEvRxOnu2gResp"
91 dlEvRxBridgeResp = "dlEvRxBridgeResp"
92 dlEvTimeoutSimple = "dlEvTimeoutSimple"
93 dlEvTimeoutBridge = "dlEvTimeoutBridge"
94 dlEvReset = "dlEvReset"
95 dlEvRestart = "dlEvRestart"
96)
97const (
98 // states of MibDownload FSM
99 dlStDisabled = "dlStDisabled"
100 dlStStarting = "dlStStarting"
101 dlStCreatingGal = "dlStCreatingGal"
102 dlStSettingOnu2g = "dlStSettingOnu2g"
103 dlStBridgeInit = "dlStBridgeInit"
104 dlStDownloaded = "dlStDownloaded"
105 dlStResetting = "dlStResetting"
106)
107
108const (
Matteo Scandolof1f39a72020-11-24 12:08:11 -0800109 // NOTE that this hardcoded to service/voltha as the MIB template is shared across stacks
Holger Hildebrandt2ff21f12020-08-13 14:38:02 +0000110 cBasePathMibTemplateKvStore = "service/voltha/omci_mibs/go_templates"
mpagenkoaf801632020-07-03 10:00:42 +0000111 cSuffixMibTemplateKvStore = "%s/%s/%s"
Matteo Scandolof1f39a72020-11-24 12:08:11 -0800112 cBasePathOnuKVStore = "%s/openonu"
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000113)
114
Himani Chawla6d2ae152020-09-02 13:11:20 +0530115// OnuDeviceEvent - event of interest to Device Adapters and OpenOMCI State Machines
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000116type OnuDeviceEvent int
117
118const (
119 // Events of interest to Device Adapters and OpenOMCI State Machines
Himani Chawla6d2ae152020-09-02 13:11:20 +0530120
121 // DeviceStatusInit - default start state
mpagenkofc4f56e2020-11-04 17:17:49 +0000122 DeviceStatusInit OnuDeviceEvent = iota
Himani Chawla6d2ae152020-09-02 13:11:20 +0530123 // MibDatabaseSync - MIB database sync (upload done)
mpagenkofc4f56e2020-11-04 17:17:49 +0000124 MibDatabaseSync
Himani Chawla6d2ae152020-09-02 13:11:20 +0530125 // OmciCapabilitiesDone - OMCI ME and message type capabilities known
mpagenkofc4f56e2020-11-04 17:17:49 +0000126 OmciCapabilitiesDone
Himani Chawla6d2ae152020-09-02 13:11:20 +0530127 // MibDownloadDone - // MIB download done
mpagenkofc4f56e2020-11-04 17:17:49 +0000128 MibDownloadDone
Himani Chawla6d2ae152020-09-02 13:11:20 +0530129 // UniLockStateDone - Uni ports admin set to lock
mpagenkofc4f56e2020-11-04 17:17:49 +0000130 UniLockStateDone
Himani Chawla6d2ae152020-09-02 13:11:20 +0530131 // UniUnlockStateDone - Uni ports admin set to unlock
mpagenkofc4f56e2020-11-04 17:17:49 +0000132 UniUnlockStateDone
mpagenko900ee4b2020-10-12 11:56:34 +0000133 // UniDisableStateDone - Uni ports admin set to lock based on device disable
mpagenkofc4f56e2020-11-04 17:17:49 +0000134 UniDisableStateDone
mpagenko900ee4b2020-10-12 11:56:34 +0000135 // UniEnableStateDone - Uni ports admin set to unlock based on device re-enable
mpagenkofc4f56e2020-11-04 17:17:49 +0000136 UniEnableStateDone
Himani Chawla6d2ae152020-09-02 13:11:20 +0530137 // PortLinkUp - Port link state change
mpagenkofc4f56e2020-11-04 17:17:49 +0000138 PortLinkUp
Himani Chawla6d2ae152020-09-02 13:11:20 +0530139 // PortLinkDw - Port link state change
mpagenkofc4f56e2020-11-04 17:17:49 +0000140 PortLinkDw
Himani Chawla6d2ae152020-09-02 13:11:20 +0530141 // OmciAniConfigDone - AniSide config according to TechProfile done
mpagenkofc4f56e2020-11-04 17:17:49 +0000142 OmciAniConfigDone
143 // OmciAniResourceRemoved - AniSide TechProfile related resource (Gem/TCont) removed
144 OmciAniResourceRemoved // needs to be the successor of OmciAniConfigDone!
145 // OmciVlanFilterAddDone - Omci Vlan config done according to flow-add
146 OmciVlanFilterAddDone
147 // OmciVlanFilterRemDone - Omci Vlan config done according to flow-remove
148 OmciVlanFilterRemDone // needs to be the successor of OmciVlanFilterAddDone!
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000149 // Add other events here as needed (alarms separate???)
150)
151
152type activityDescr struct {
Himani Chawla4d908332020-08-31 12:30:20 +0530153 databaseClass func() error
154 //advertiseEvents bool
155 auditDelay uint16
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000156 //tasks map[string]func() error
157}
Himani Chawla6d2ae152020-09-02 13:11:20 +0530158
159// OmciDeviceFsms - FSM event mapping to database class and time to wait between audits
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000160type OmciDeviceFsms map[string]activityDescr
161
Himani Chawla6d2ae152020-09-02 13:11:20 +0530162// AdapterFsm - Adapter FSM details including channel, event and device
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000163type AdapterFsm struct {
164 fsmName string
165 deviceID string
166 commChan chan Message
167 pFsm *fsm.FSM
168}
169
Himani Chawla6d2ae152020-09-02 13:11:20 +0530170//NewAdapterFsm - FSM details including event, device and channel.
171func NewAdapterFsm(aName string, aDeviceID string, aCommChannel chan Message) *AdapterFsm {
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000172 aFsm := &AdapterFsm{
Himani Chawla6d2ae152020-09-02 13:11:20 +0530173 fsmName: aName,
174 deviceID: aDeviceID,
175 commChan: aCommChannel,
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000176 }
177 return aFsm
178}
179
180//Start starts (logs) the omci agent
181func (oo *AdapterFsm) logFsmStateChange(e *fsm.Event) {
182 logger.Debugw("FSM state change", log.Fields{"device-id": oo.deviceID, "FSM name": oo.fsmName,
183 "event name": string(e.Event), "src state": string(e.Src), "dst state": string(e.Dst)})
184}
185
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000186//OntDeviceEntry structure holds information about the attached FSM'as and their communication
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000187
188const (
Himani Chawla6d2ae152020-09-02 13:11:20 +0530189 firstSwImageMeID = 0
190 secondSwImageMeID = 1
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000191)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530192const onugMeID = 0
193const onu2gMeID = 0
194const ipHostConfigDataMeID = 1
195const onugSerialNumberLen = 8
196const omciMacAddressLen = 6
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000197
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000198const cEmptyMacAddrString = "000000000000"
199const cEmptySerialNumberString = "0000000000000000"
200
Himani Chawla6d2ae152020-09-02 13:11:20 +0530201type swImages struct {
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000202 version string
203 isActive uint8
204}
205
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000206type uniPersConfig struct {
207 PersUniID uint8 `json:"uni_id"`
Girish Gowdra041dcb32020-11-16 16:54:30 -0800208 PersTpPathMap map[uint8]string `json:"PersTpPathMap"` // tp-id to tp-path map
209 PersFlowParams []uniVlanFlowParams `json:"flow_params"` //as defined in omci_ani_config.go
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000210}
211
212type onuPersistentData struct {
213 PersOnuID uint32 `json:"onu_id"`
214 PersIntfID uint32 `json:"intf_id"`
215 PersSnr string `json:"serial_number"`
216 PersAdminState string `json:"admin_state"`
217 PersOperState string `json:"oper_state"`
218 PersUniConfig []uniPersConfig `json:"uni_config"`
219}
220
Himani Chawla6d2ae152020-09-02 13:11:20 +0530221// OnuDeviceEntry - ONU device info and FSM events.
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000222type OnuDeviceEntry struct {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000223 deviceID string
224 baseDeviceHandler *deviceHandler
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000225 pOpenOnuAc *OpenONUAC
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000226 coreProxy adapterif.CoreProxy
227 adapterProxy adapterif.AdapterProxy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000228 PDevOmciCC *omciCC
229 pOnuDB *onuDeviceDB
230 mibTemplateKVStore *db.Backend
231 sOnuPersistentData onuPersistentData
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000232 mibTemplatePath string
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000233 onuKVStoreMutex sync.RWMutex
234 onuKVStore *db.Backend
235 onuKVStorePath string
236 onuKVStoreprocResult error //error indication of processing
237 chOnuKvProcessingStep chan uint8
238 vendorID string
239 serialNumber string
240 equipmentID string
241 swImages [secondSwImageMeID + 1]swImages
242 activeSwVersion string
243 macAddress string
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000244 //lockDeviceEntries sync.RWMutex
245 mibDbClass func() error
246 supportedFsms OmciDeviceFsms
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000247 devState OnuDeviceEvent
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000248 // for mibUpload
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000249 mibAuditDelay uint16
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000250
251 // for mibUpload
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000252 pMibUploadFsm *AdapterFsm //could be handled dynamically and more general as pAdapterFsm - perhaps later
253 // for mibDownload
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000254 pMibDownloadFsm *AdapterFsm //could be handled dynamically and more general as pAdapterFsm - perhaps later
255 //remark: general usage of pAdapterFsm would require generalization of commChan usage and internal event setting
256 // within the FSM event procedures
ozgecanetsiae11479f2020-07-06 09:44:47 +0300257 omciMessageReceived chan bool //seperate channel needed by DownloadFsm
258 omciRebootMessageReceivedChannel chan Message // channel needed by Reboot request
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000259}
260
Himani Chawla6d2ae152020-09-02 13:11:20 +0530261//newOnuDeviceEntry returns a new instance of a OnuDeviceEntry
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000262//mib_db (as well as not inluded alarm_db not really used in this code? VERIFY!!)
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000263func newOnuDeviceEntry(ctx context.Context, dh *deviceHandler) *OnuDeviceEntry {
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000264 logger.Debugw("init-onuDeviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000265 var onuDeviceEntry OnuDeviceEntry
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000266 onuDeviceEntry.deviceID = dh.deviceID
267 onuDeviceEntry.baseDeviceHandler = dh
268 onuDeviceEntry.pOpenOnuAc = dh.pOpenOnuAc
269 onuDeviceEntry.coreProxy = dh.coreProxy
270 onuDeviceEntry.adapterProxy = dh.AdapterProxy
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000271 onuDeviceEntry.devState = DeviceStatusInit
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000272 onuDeviceEntry.sOnuPersistentData.PersUniConfig = make([]uniPersConfig, 0)
273 onuDeviceEntry.chOnuKvProcessingStep = make(chan uint8)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300274 onuDeviceEntry.omciRebootMessageReceivedChannel = make(chan Message, 2048)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000275 //openomciagent.lockDeviceHandlersMap = sync.RWMutex{}
276 //OMCI related databases are on a per-agent basis. State machines and tasks
277 //are per ONU Vendor
278 //
279 // MIB Synchronization Database - possible overloading from arguments
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000280 if dh.pOpenOnuAc.pSupportedFsms != nil {
281 onuDeviceEntry.supportedFsms = *dh.pOpenOnuAc.pSupportedFsms
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000282 } else {
283 //var mibSyncFsm = NewMibSynchronizer()
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000284 // use some internaö defaults, if not defined from outside
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000285 onuDeviceEntry.supportedFsms = OmciDeviceFsms{
286 "mib-synchronizer": {
287 //mibSyncFsm, // Implements the MIB synchronization state machine
Himani Chawla6d2ae152020-09-02 13:11:20 +0530288 onuDeviceEntry.mibDbVolatileDict, // Implements volatile ME MIB database
Himani Chawla4d908332020-08-31 12:30:20 +0530289 //true, // Advertise events on OpenOMCI event bus
290 60, // Time to wait between MIB audits. 0 to disable audits.
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000291 // map[string]func() error{
292 // "mib-upload": onuDeviceEntry.MibUploadTask,
293 // "mib-template": onuDeviceEntry.MibTemplateTask,
294 // "get-mds": onuDeviceEntry.GetMdsTask,
295 // "mib-audit": onuDeviceEntry.GetMdsTask,
296 // "mib-resync": onuDeviceEntry.MibResyncTask,
297 // "mib-reconcile": onuDeviceEntry.MibReconcileTask,
298 // },
299 },
300 }
301 }
302 onuDeviceEntry.mibDbClass = onuDeviceEntry.supportedFsms["mib-synchronizer"].databaseClass
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000303 logger.Debug("access2mibDbClass")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000304 go onuDeviceEntry.mibDbClass()
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000305 onuDeviceEntry.mibAuditDelay = onuDeviceEntry.supportedFsms["mib-synchronizer"].auditDelay
306 logger.Debugw("MibAudit is set to", log.Fields{"Delay": onuDeviceEntry.mibAuditDelay})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000307
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000308 // Omci related Mib upload sync state machine
309 mibUploadChan := make(chan Message, 2048)
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000310 onuDeviceEntry.pMibUploadFsm = NewAdapterFsm("MibUpload", dh.deviceID, mibUploadChan)
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000311 onuDeviceEntry.pMibUploadFsm.pFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000312 ulStDisabled,
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000313 fsm.Events{
314
mpagenko1cc3cb42020-07-27 15:24:38 +0000315 {Name: ulEvStart, Src: []string{ulStDisabled}, Dst: ulStStarting},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000316
mpagenko1cc3cb42020-07-27 15:24:38 +0000317 {Name: ulEvResetMib, Src: []string{ulStStarting}, Dst: ulStResettingMib},
318 {Name: ulEvGetVendorAndSerial, Src: []string{ulStResettingMib}, Dst: ulStGettingVendorAndSerial},
Himani Chawla4d908332020-08-31 12:30:20 +0530319 {Name: ulEvGetEquipmentID, Src: []string{ulStGettingVendorAndSerial}, Dst: ulStGettingEquipmentID},
320 {Name: ulEvGetFirstSwVersion, Src: []string{ulStGettingEquipmentID}, Dst: ulStGettingFirstSwVersion},
mpagenko1cc3cb42020-07-27 15:24:38 +0000321 {Name: ulEvGetSecondSwVersion, Src: []string{ulStGettingFirstSwVersion}, Dst: ulStGettingSecondSwVersion},
322 {Name: ulEvGetMacAddress, Src: []string{ulStGettingSecondSwVersion}, Dst: ulStGettingMacAddress},
323 {Name: ulEvGetMibTemplate, Src: []string{ulStGettingMacAddress}, Dst: ulStGettingMibTemplate},
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000324
mpagenko1cc3cb42020-07-27 15:24:38 +0000325 {Name: ulEvUploadMib, Src: []string{ulStGettingMibTemplate}, Dst: ulStUploading},
326 {Name: ulEvExamineMds, Src: []string{ulStStarting}, Dst: ulStExaminingMds},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000327
mpagenko1cc3cb42020-07-27 15:24:38 +0000328 {Name: ulEvSuccess, Src: []string{ulStGettingMibTemplate}, Dst: ulStInSync},
329 {Name: ulEvSuccess, Src: []string{ulStUploading}, Dst: ulStInSync},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000330
mpagenko1cc3cb42020-07-27 15:24:38 +0000331 {Name: ulEvSuccess, Src: []string{ulStExaminingMds}, Dst: ulStInSync},
332 {Name: ulEvMismatch, Src: []string{ulStExaminingMds}, Dst: ulStResynchronizing},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000333
mpagenko1cc3cb42020-07-27 15:24:38 +0000334 {Name: ulEvAuditMib, Src: []string{ulStInSync}, Dst: ulStAuditing},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000335
mpagenko1cc3cb42020-07-27 15:24:38 +0000336 {Name: ulEvSuccess, Src: []string{ulStOutOfSync}, Dst: ulStInSync},
337 {Name: ulEvAuditMib, Src: []string{ulStOutOfSync}, Dst: ulStAuditing},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000338
mpagenko1cc3cb42020-07-27 15:24:38 +0000339 {Name: ulEvSuccess, Src: []string{ulStAuditing}, Dst: ulStInSync},
340 {Name: ulEvMismatch, Src: []string{ulStAuditing}, Dst: ulStResynchronizing},
341 {Name: ulEvForceResync, Src: []string{ulStAuditing}, Dst: ulStResynchronizing},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000342
mpagenko1cc3cb42020-07-27 15:24:38 +0000343 {Name: ulEvSuccess, Src: []string{ulStResynchronizing}, Dst: ulStInSync},
344 {Name: ulEvDiffsFound, Src: []string{ulStResynchronizing}, Dst: ulStOutOfSync},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000345
Himani Chawla4d908332020-08-31 12:30:20 +0530346 {Name: ulEvTimeout, Src: []string{ulStResettingMib, ulStGettingVendorAndSerial, ulStGettingEquipmentID, ulStGettingFirstSwVersion,
mpagenko1cc3cb42020-07-27 15:24:38 +0000347 ulStGettingSecondSwVersion, ulStGettingMacAddress, ulStGettingMibTemplate, ulStUploading, ulStResynchronizing, ulStExaminingMds,
348 ulStInSync, ulStOutOfSync, ulStAuditing}, Dst: ulStStarting},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000349
Himani Chawla4d908332020-08-31 12:30:20 +0530350 {Name: ulEvStop, Src: []string{ulStStarting, ulStResettingMib, ulStGettingVendorAndSerial, ulStGettingEquipmentID, ulStGettingFirstSwVersion,
mpagenko1cc3cb42020-07-27 15:24:38 +0000351 ulStGettingSecondSwVersion, ulStGettingMacAddress, ulStGettingMibTemplate, ulStUploading, ulStResynchronizing, ulStExaminingMds,
352 ulStInSync, ulStOutOfSync, ulStAuditing}, Dst: ulStDisabled},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000353 },
354
355 fsm.Callbacks{
Girish Gowdra041dcb32020-11-16 16:54:30 -0800356 "enter_state": func(e *fsm.Event) { onuDeviceEntry.pMibUploadFsm.logFsmStateChange(e) },
357 "enter_" + ulStStarting: func(e *fsm.Event) { onuDeviceEntry.enterStartingState(e) },
358 "enter_" + ulStResettingMib: func(e *fsm.Event) { onuDeviceEntry.enterResettingMibState(e) },
359 "enter_" + ulStGettingVendorAndSerial: func(e *fsm.Event) { onuDeviceEntry.enterGettingVendorAndSerialState(e) },
360 "enter_" + ulStGettingEquipmentID: func(e *fsm.Event) { onuDeviceEntry.enterGettingEquipmentIDState(e) },
361 "enter_" + ulStGettingFirstSwVersion: func(e *fsm.Event) { onuDeviceEntry.enterGettingFirstSwVersionState(e) },
362 "enter_" + ulStGettingSecondSwVersion: func(e *fsm.Event) { onuDeviceEntry.enterGettingSecondSwVersionState(e) },
363 "enter_" + ulStGettingMacAddress: func(e *fsm.Event) { onuDeviceEntry.enterGettingMacAddressState(e) },
364 "enter_" + ulStGettingMibTemplate: func(e *fsm.Event) { onuDeviceEntry.enterGettingMibTemplate(e) },
365 "enter_" + ulStUploading: func(e *fsm.Event) { onuDeviceEntry.enterUploadingState(e) },
366 "enter_" + ulStExaminingMds: func(e *fsm.Event) { onuDeviceEntry.enterExaminingMdsState(e) },
367 "enter_" + ulStResynchronizing: func(e *fsm.Event) { onuDeviceEntry.enterResynchronizingState(e) },
368 "enter_" + ulStAuditing: func(e *fsm.Event) { onuDeviceEntry.enterAuditingState(e) },
369 "enter_" + ulStOutOfSync: func(e *fsm.Event) { onuDeviceEntry.enterOutOfSyncState(e) },
370 "enter_" + ulStInSync: func(e *fsm.Event) { onuDeviceEntry.enterInSyncState(e) },
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000371 },
372 )
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000373 // Omci related Mib download state machine
374 mibDownloadChan := make(chan Message, 2048)
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000375 onuDeviceEntry.pMibDownloadFsm = NewAdapterFsm("MibDownload", dh.deviceID, mibDownloadChan)
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000376 onuDeviceEntry.pMibDownloadFsm.pFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000377 dlStDisabled,
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000378 fsm.Events{
379
mpagenko1cc3cb42020-07-27 15:24:38 +0000380 {Name: dlEvStart, Src: []string{dlStDisabled}, Dst: dlStStarting},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000381
mpagenko1cc3cb42020-07-27 15:24:38 +0000382 {Name: dlEvCreateGal, Src: []string{dlStStarting}, Dst: dlStCreatingGal},
383 {Name: dlEvRxGalResp, Src: []string{dlStCreatingGal}, Dst: dlStSettingOnu2g},
384 {Name: dlEvRxOnu2gResp, Src: []string{dlStSettingOnu2g}, Dst: dlStBridgeInit},
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000385 // the bridge state is used for multi ME config for alle UNI related ports
386 // maybe such could be reflected in the state machine as well (port number parametrized)
387 // but that looks not straightforward here - so we keep it simple here for the beginning(?)
mpagenko1cc3cb42020-07-27 15:24:38 +0000388 {Name: dlEvRxBridgeResp, Src: []string{dlStBridgeInit}, Dst: dlStDownloaded},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000389
mpagenko1cc3cb42020-07-27 15:24:38 +0000390 {Name: dlEvTimeoutSimple, Src: []string{dlStCreatingGal, dlStSettingOnu2g}, Dst: dlStStarting},
391 {Name: dlEvTimeoutBridge, Src: []string{dlStBridgeInit}, Dst: dlStStarting},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000392
mpagenko1cc3cb42020-07-27 15:24:38 +0000393 {Name: dlEvReset, Src: []string{dlStStarting, dlStCreatingGal, dlStSettingOnu2g,
394 dlStBridgeInit, dlStDownloaded}, Dst: dlStResetting},
395 // exceptional treatment for all states except dlStResetting
396 {Name: dlEvRestart, Src: []string{dlStStarting, dlStCreatingGal, dlStSettingOnu2g,
397 dlStBridgeInit, dlStDownloaded, dlStResetting}, Dst: dlStDisabled},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000398 },
399
400 fsm.Callbacks{
Girish Gowdra041dcb32020-11-16 16:54:30 -0800401 "enter_state": func(e *fsm.Event) { onuDeviceEntry.pMibDownloadFsm.logFsmStateChange(e) },
402 "enter_" + dlStStarting: func(e *fsm.Event) { onuDeviceEntry.enterDLStartingState(e) },
403 "enter_" + dlStCreatingGal: func(e *fsm.Event) { onuDeviceEntry.enterCreatingGalState(e) },
404 "enter_" + dlStSettingOnu2g: func(e *fsm.Event) { onuDeviceEntry.enterSettingOnu2gState(e) },
405 "enter_" + dlStBridgeInit: func(e *fsm.Event) { onuDeviceEntry.enterBridgeInitState(e) },
406 "enter_" + dlStDownloaded: func(e *fsm.Event) { onuDeviceEntry.enterDownloadedState(e) },
407 "enter_" + dlStResetting: func(e *fsm.Event) { onuDeviceEntry.enterResettingState(e) },
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000408 },
409 )
410 if onuDeviceEntry.pMibDownloadFsm == nil || onuDeviceEntry.pMibDownloadFsm.pFsm == nil {
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000411 logger.Errorw("MibDownloadFsm could not be instantiated", log.Fields{"device-id": dh.deviceID})
Andrea Campanella6515c582020-10-05 11:25:00 +0200412 // TODO some specifc error treatment - or waiting for crash ?
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000413 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000414
Himani Chawla6d2ae152020-09-02 13:11:20 +0530415 onuDeviceEntry.mibTemplateKVStore = onuDeviceEntry.baseDeviceHandler.setBackend(cBasePathMibTemplateKvStore)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000416 if onuDeviceEntry.mibTemplateKVStore == nil {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000417 logger.Errorw("Can't access mibTemplateKVStore - no backend connection to service",
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000418 log.Fields{"device-id": dh.deviceID, "service": cBasePathMibTemplateKvStore})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000419 }
420
421 onuDeviceEntry.onuKVStorePath = onuDeviceEntry.deviceID
Matteo Scandolof1f39a72020-11-24 12:08:11 -0800422 baseKvStorePath := fmt.Sprintf(cBasePathOnuKVStore, dh.pOpenOnuAc.cm.Backend.PathPrefix)
423 onuDeviceEntry.onuKVStore = onuDeviceEntry.baseDeviceHandler.setBackend(baseKvStorePath)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000424 if onuDeviceEntry.onuKVStore == nil {
425 logger.Errorw("Can't access onuKVStore - no backend connection to service",
Matteo Scandolof1f39a72020-11-24 12:08:11 -0800426 log.Fields{"device-id": dh.deviceID, "service": baseKvStorePath})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000427 }
428
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000429 // Alarm Synchronization Database
430 //self._alarm_db = None
431 //self._alarm_database_cls = support_classes['alarm-synchronizer']['database']
432 return &onuDeviceEntry
433}
434
Himani Chawla6d2ae152020-09-02 13:11:20 +0530435//start starts (logs) the omci agent
436func (oo *OnuDeviceEntry) start(ctx context.Context) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000437 logger.Debugw("OnuDeviceEntry-starting", log.Fields{"for device-id": oo.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000438 if oo.PDevOmciCC == nil {
mpagenko900ee4b2020-10-12 11:56:34 +0000439 oo.PDevOmciCC = newOmciCC(ctx, oo, oo.deviceID, oo.baseDeviceHandler,
440 oo.coreProxy, oo.adapterProxy)
441 if oo.PDevOmciCC == nil {
442 logger.Errorw("Could not create devOmciCc - abort", log.Fields{"for device-id": oo.deviceID})
443 return fmt.Errorf("could not create devOmciCc %s", oo.deviceID)
444 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000445 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000446 return nil
447}
448
mpagenko900ee4b2020-10-12 11:56:34 +0000449//stop stops/resets the omciCC
450func (oo *OnuDeviceEntry) stop(ctx context.Context, abResetOmciCC bool) error {
451 logger.Debugw("OnuDeviceEntry-stopping", log.Fields{"for device-id": oo.deviceID})
452 if abResetOmciCC && (oo.PDevOmciCC != nil) {
453 _ = oo.PDevOmciCC.stop(ctx)
454 }
455 //to allow for all event notifications again when re-using the device and omciCC
456 oo.devState = DeviceStatusInit
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000457 return nil
458}
459
Himani Chawla6d2ae152020-09-02 13:11:20 +0530460func (oo *OnuDeviceEntry) reboot(ctx context.Context) error {
mpagenko900ee4b2020-10-12 11:56:34 +0000461 logger.Debugw("OnuDeviceEntry-rebooting", log.Fields{"for device-id": oo.deviceID})
462 if oo.PDevOmciCC != nil {
463 if err := oo.PDevOmciCC.sendReboot(ctx, ConstDefaultOmciTimeout, true, oo.omciRebootMessageReceivedChannel); err != nil {
464 logger.Errorw("onu didn't reboot", log.Fields{"for device-id": oo.deviceID})
465 return err
466 }
ozgecanetsiae11479f2020-07-06 09:44:47 +0300467 }
ozgecanetsiae11479f2020-07-06 09:44:47 +0300468 return nil
469}
470
471func (oo *OnuDeviceEntry) waitForRebootResponse(responseChannel chan Message) error {
472 select {
473 case <-time.After(3 * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
474 logger.Warnw("Reboot timeout", log.Fields{"for device-id": oo.deviceID})
Andrea Campanella6515c582020-10-05 11:25:00 +0200475 return fmt.Errorf("rebootTimeout")
ozgecanetsiae11479f2020-07-06 09:44:47 +0300476 case data := <-responseChannel:
477 switch data.Data.(OmciMessage).OmciMsg.MessageType {
478 case omci.RebootResponseType:
479 {
480 msgLayer := (*data.Data.(OmciMessage).OmciPacket).Layer(omci.LayerTypeRebootResponse)
481 if msgLayer == nil {
Andrea Campanella6515c582020-10-05 11:25:00 +0200482 return fmt.Errorf("omci Msg layer could not be detected for RebootResponseType")
ozgecanetsiae11479f2020-07-06 09:44:47 +0300483 }
Andrea Campanellabef4e542020-10-22 11:01:28 +0200484 msgObj, msgOk := msgLayer.(*omci.RebootResponse)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300485 if !msgOk {
Andrea Campanella6515c582020-10-05 11:25:00 +0200486 return fmt.Errorf("omci Msg layer could not be assigned for RebootResponseType %s", oo.deviceID)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300487 }
Andrea Campanellabef4e542020-10-22 11:01:28 +0200488 logger.Debugw("RebootResponse data", log.Fields{"device-id": oo.deviceID, "data-fields": msgObj})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300489 if msgObj.Result != me.Success {
mpagenko01e726e2020-10-23 09:45:29 +0000490 logger.Errorw("Omci RebootResponse result error", log.Fields{"device-id": oo.deviceID, "Error": msgObj.Result})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300491 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
Andrea Campanellabef4e542020-10-22 11:01:28 +0200492 return fmt.Errorf("omci RebootResponse result error indication %s for device %s",
Andrea Campanella6515c582020-10-05 11:25:00 +0200493 msgObj.Result, oo.deviceID)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300494 }
495 return nil
496 }
497 }
mpagenko01e726e2020-10-23 09:45:29 +0000498 logger.Warnw("Reboot response message type error", log.Fields{"for device-id": oo.deviceID})
Andrea Campanella6515c582020-10-05 11:25:00 +0200499 return fmt.Errorf("unexpected OmciResponse type received %s", oo.deviceID)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300500 }
501}
502
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000503//Relay the InSync message via Handler to Rw core - Status update
Himani Chawla26e555c2020-08-31 12:30:20 +0530504func (oo *OnuDeviceEntry) transferSystemEvent(devEvent OnuDeviceEvent) {
505 logger.Debugw("relaying system-event", log.Fields{"Event": devEvent})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000506 // decouple the handler transfer from further processing here
507 // TODO!!! check if really no synch is required within the system e.g. to ensure following steps ..
Himani Chawla26e555c2020-08-31 12:30:20 +0530508 if devEvent == MibDatabaseSync {
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000509 if oo.devState < MibDatabaseSync { //devState has not been synced yet
510 oo.devState = MibDatabaseSync
Himani Chawla6d2ae152020-09-02 13:11:20 +0530511 go oo.baseDeviceHandler.deviceProcStatusUpdate(devEvent)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000512 //TODO!!! device control: next step: start MIB capability verification from here ?!!!
513 } else {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000514 logger.Debugw("mibinsync-event in some already synced state - ignored", log.Fields{"state": oo.devState})
515 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530516 } else if devEvent == MibDownloadDone {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000517 if oo.devState < MibDownloadDone { //devState has not been synced yet
518 oo.devState = MibDownloadDone
Himani Chawla6d2ae152020-09-02 13:11:20 +0530519 go oo.baseDeviceHandler.deviceProcStatusUpdate(devEvent)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000520 } else {
521 logger.Debugw("mibdownloaddone-event was already seen - ignored", log.Fields{"state": oo.devState})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000522 }
523 } else {
Himani Chawla26e555c2020-08-31 12:30:20 +0530524 logger.Warnw("device-event not yet handled", log.Fields{"state": devEvent})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000525 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000526}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000527
528func (oo *OnuDeviceEntry) restoreDataFromOnuKvStore(ctx context.Context) error {
529 if oo.onuKVStore == nil {
530 logger.Debugw("onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
531 return fmt.Errorf(fmt.Sprintf("onuKVStore-not-set-abort-%s", oo.deviceID))
532 }
533 oo.sOnuPersistentData = onuPersistentData{0, 0, "", "", "", make([]uniPersConfig, 0)}
534 Value, err := oo.onuKVStore.Get(ctx, oo.onuKVStorePath)
535 if err == nil {
536 if Value != nil {
537 logger.Debugw("ONU-data read",
538 log.Fields{"Key": Value.Key, "device-id": oo.deviceID})
539 tmpBytes, _ := kvstore.ToByte(Value.Value)
540
541 if err = json.Unmarshal(tmpBytes, &oo.sOnuPersistentData); err != nil {
542 logger.Errorw("unable to unmarshal ONU-data", log.Fields{"error": err, "device-id": oo.deviceID})
543 return fmt.Errorf(fmt.Sprintf("unable-to-unmarshal-ONU-data-%s", oo.deviceID))
544 }
545 logger.Debugw("ONU-data", log.Fields{"sOnuPersistentData": oo.sOnuPersistentData,
546 "device-id": oo.deviceID})
547 } else {
mpagenko2418ab02020-11-12 12:58:06 +0000548 logger.Debugw("no ONU-data found", log.Fields{"path": oo.onuKVStorePath, "device-id": oo.deviceID})
549 return fmt.Errorf("no-ONU-data-found")
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000550 }
551 } else {
552 logger.Errorw("unable to read from KVstore", log.Fields{"device-id": oo.deviceID})
553 return fmt.Errorf(fmt.Sprintf("unable-to-read-from-KVstore-%s", oo.deviceID))
554 }
555 return nil
556}
557
558func (oo *OnuDeviceEntry) deleteDataFromOnuKvStore(ctx context.Context, wg *sync.WaitGroup) {
559 defer wg.Done()
560
561 if oo.onuKVStore == nil {
562 logger.Debugw("onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
563 oo.onuKVStoreprocResult = errors.New("onu-data delete aborted: onuKVStore not set")
564 return
565 }
566 var processingStep uint8 = 1 // used to synchronize the different processing steps with chOnuKvProcessingStep
567 go oo.deletePersistentData(ctx, processingStep)
568 if !oo.waitForTimeoutOrCompletion(ctx, oo.chOnuKvProcessingStep, processingStep) {
569 //timeout or error detected
570 logger.Debugw("ONU-data not deleted - abort", log.Fields{"device-id": oo.deviceID})
571 oo.onuKVStoreprocResult = errors.New("onu-data delete aborted: during kv-access")
572 return
573 }
574}
575
576func (oo *OnuDeviceEntry) deletePersistentData(ctx context.Context, aProcessingStep uint8) {
577
mpagenko2418ab02020-11-12 12:58:06 +0000578 logger.Debugw("delete and clear internal persistency data", log.Fields{"device-id": oo.deviceID})
579 oo.sOnuPersistentData.PersUniConfig = nil //releasing all UniConfig entries to garbage collector
580 oo.sOnuPersistentData = onuPersistentData{0, 0, "", "", "", make([]uniPersConfig, 0)} //default entry
581
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000582 logger.Debugw("delete ONU-data from KVStore", log.Fields{"device-id": oo.deviceID})
583 err := oo.onuKVStore.Delete(ctx, oo.onuKVStorePath)
584 if err != nil {
585 logger.Errorw("unable to delete in KVstore", log.Fields{"device-id": oo.deviceID, "err": err})
586 oo.chOnuKvProcessingStep <- 0 //error indication
587 return
588 }
589 oo.chOnuKvProcessingStep <- aProcessingStep //done
590}
591
592func (oo *OnuDeviceEntry) updateOnuKvStore(ctx context.Context, wg *sync.WaitGroup) {
593 defer wg.Done()
594
595 if oo.onuKVStore == nil {
596 logger.Debugw("onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
597 oo.onuKVStoreprocResult = errors.New("onu-data update aborted: onuKVStore not set")
598 return
599 }
600 var processingStep uint8 = 1 // used to synchronize the different processing steps with chOnuKvProcessingStep
601 go oo.storeDataInOnuKvStore(ctx, processingStep)
602 if !oo.waitForTimeoutOrCompletion(ctx, oo.chOnuKvProcessingStep, processingStep) {
603 //timeout or error detected
604 logger.Debugw("ONU-data not written - abort", log.Fields{"device-id": oo.deviceID})
605 oo.onuKVStoreprocResult = errors.New("onu-data update aborted: during writing process")
606 return
607 }
608}
609
610func (oo *OnuDeviceEntry) storeDataInOnuKvStore(ctx context.Context, aProcessingStep uint8) {
611
612 //assign values which are not already present when newOnuDeviceEntry() is called
613 oo.sOnuPersistentData.PersOnuID = oo.baseDeviceHandler.pOnuIndication.OnuId
614 oo.sOnuPersistentData.PersIntfID = oo.baseDeviceHandler.pOnuIndication.IntfId
615 oo.sOnuPersistentData.PersSnr = oo.baseDeviceHandler.pOnuOmciDevice.serialNumber
616 //TODO: verify usage of these values during restart UC
617 oo.sOnuPersistentData.PersAdminState = "up"
618 oo.sOnuPersistentData.PersOperState = "active"
619
620 logger.Debugw("Update ONU-data in KVStore", log.Fields{"device-id": oo.deviceID, "sOnuPersistentData": oo.sOnuPersistentData})
621
622 Value, err := json.Marshal(oo.sOnuPersistentData)
623 if err != nil {
624 logger.Errorw("unable to marshal ONU-data", log.Fields{"sOnuPersistentData": oo.sOnuPersistentData,
625 "device-id": oo.deviceID, "err": err})
626 oo.chOnuKvProcessingStep <- 0 //error indication
627 return
628 }
629 err = oo.onuKVStore.Put(ctx, oo.onuKVStorePath, Value)
630 if err != nil {
631 logger.Errorw("unable to write ONU-data into KVstore", log.Fields{"device-id": oo.deviceID, "err": err})
632 oo.chOnuKvProcessingStep <- 0 //error indication
633 return
634 }
635 oo.chOnuKvProcessingStep <- aProcessingStep //done
636}
637
Girish Gowdra041dcb32020-11-16 16:54:30 -0800638func (oo *OnuDeviceEntry) updateOnuUniTpPath(aUniID uint8, aTpID uint8, aPathString string) bool {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000639 /* within some specific InterAdapter processing request write/read access to data is ensured to be sequentially,
640 as also the complete sequence is ensured to 'run to completion' before some new request is accepted
641 no specific concurrency protection to sOnuPersistentData is required here
642 */
643 for k, v := range oo.sOnuPersistentData.PersUniConfig {
644 if v.PersUniID == aUniID {
645 logger.Debugw("PersUniConfig-entry already exists", log.Fields{"device-id": oo.deviceID, "uniID": aUniID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800646 existingPath, ok := oo.sOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID]
647 if !ok {
648 logger.Debugw("tp-does-not-exist--to-be-created-afresh", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "tpID": aTpID, "path": aPathString})
649 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000650 if existingPath != aPathString {
651 if aPathString == "" {
652 //existing entry to be deleted
653 logger.Debugw("UniTp delete path value", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800654 oo.sOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID] = ""
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000655 } else {
656 //existing entry to be modified
657 logger.Debugw("UniTp modify path value", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800658 oo.sOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID] = aPathString
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000659 }
660 return true
661 }
662 //entry already exists
mpagenkofc4f56e2020-11-04 17:17:49 +0000663 if aPathString == "" {
664 //no active TechProfile
665 logger.Debugw("UniTp path has already been removed - no AniSide config to be removed", log.Fields{
666 "device-id": oo.deviceID, "uniID": aUniID})
667 // attention 201105: this block is at the moment entered for each of subsequent GemPortDeletes and TContDelete
668 // as the path is already cleared with the first GemPort - this will probably change with the upcoming real
669 // TechProfile removal (still TODO), but anyway the reasonUpdate initiated here should not harm overall behavior
670 go oo.baseDeviceHandler.deviceProcStatusUpdate(OmciAniResourceRemoved)
671 // no flow config pending on 'remove' so far
672 } else {
673 //the given TechProfile already exists and is assumed to be active - update devReason as if the config has been done here
674 //was needed e.g. in voltha POD Tests:Validate authentication on a disabled ONU
675 // (as here the TechProfile has not been removed with the disable-device before the new enable-device)
676 logger.Debugw("UniTp path already exists - TechProfile supposed to be active", log.Fields{
677 "device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
678 //no deviceReason update (deviceProcStatusUpdate) here to ensure 'omci_flows_pushed' state within disable/enable procedure of ATT scenario
679 // (during which the flows are removed/re-assigned but the techProf is left active)
680 //and as the TechProfile is regarded as active we have to verify, if some flow configuration still waits on it
681 // (should not be the case, but should not harm or be more robust ...)
mpagenko2418ab02020-11-12 12:58:06 +0000682 // and to be sure, that for some reason the corresponding TpDelete was lost somewhere in history
683 // we also reset a possibly outstanding delete request - repeated TpConfig is regarded as valid for waiting flow config
684 if oo.baseDeviceHandler.pOnuTP != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -0800685 oo.baseDeviceHandler.pOnuTP.setProfileToDelete(aUniID, aTpID, false)
mpagenko2418ab02020-11-12 12:58:06 +0000686 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000687 go oo.baseDeviceHandler.VerifyVlanConfigRequest(aUniID)
688 }
689 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 +0000690 }
691 }
692 //no entry exists for uniId
693
694 if aPathString == "" {
695 //delete request in non-existing state , accept as no change
696 logger.Debugw("UniTp path already removed", log.Fields{"device-id": oo.deviceID, "uniID": aUniID})
697 return false
698 }
699 //new entry to be created
700 logger.Debugw("New UniTp path set", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800701 perSubTpPathMap := make(map[uint8]string)
702 perSubTpPathMap[aTpID] = aPathString
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000703 oo.sOnuPersistentData.PersUniConfig =
Girish Gowdra041dcb32020-11-16 16:54:30 -0800704 append(oo.sOnuPersistentData.PersUniConfig, uniPersConfig{PersUniID: aUniID, PersTpPathMap: perSubTpPathMap, PersFlowParams: make([]uniVlanFlowParams, 0)})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000705 return true
706}
707
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000708func (oo *OnuDeviceEntry) updateOnuUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) {
709
710 for k, v := range oo.sOnuPersistentData.PersUniConfig {
711 if v.PersUniID == aUniID {
712 oo.sOnuPersistentData.PersUniConfig[k].PersFlowParams = make([]uniVlanFlowParams, len(*aUniVlanFlowParams))
713 copy(oo.sOnuPersistentData.PersUniConfig[k].PersFlowParams, *aUniVlanFlowParams)
714 return
715 }
716 }
717 //flow update was faster than tp-config - create PersUniConfig-entry
Girish Gowdra041dcb32020-11-16 16:54:30 -0800718 tmpConfig := uniPersConfig{PersUniID: aUniID, PersTpPathMap: make(map[uint8]string), PersFlowParams: make([]uniVlanFlowParams, len(*aUniVlanFlowParams))}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000719 copy(tmpConfig.PersFlowParams, *aUniVlanFlowParams)
720 oo.sOnuPersistentData.PersUniConfig = append(oo.sOnuPersistentData.PersUniConfig, tmpConfig)
721}
722
723func (oo *OnuDeviceEntry) waitForTimeoutOrCompletion(
724 ctx context.Context, aChOnuProcessingStep <-chan uint8, aProcessingStep uint8) bool {
725 select {
726 case <-ctx.Done():
727 logger.Warnw("processing not completed in-time!",
728 log.Fields{"device-id": oo.deviceID, "error": ctx.Err()})
729 return false
730 case rxStep := <-aChOnuProcessingStep:
731 if rxStep == aProcessingStep {
732 return true
733 }
734 //all other values are not accepted - including 0 for error indication
735 logger.Warnw("Invalid processing step received: abort!",
736 log.Fields{"device-id": oo.deviceID,
737 "wantedStep": aProcessingStep, "haveStep": rxStep})
738 return false
739 }
740}
741
742func (oo *OnuDeviceEntry) resetKvProcessingErrorIndication() {
743 oo.onuKVStoreprocResult = nil
744}
745func (oo *OnuDeviceEntry) getKvProcessingErrorIndication() error {
746 return oo.onuKVStoreprocResult
747}
748
749func (oo *OnuDeviceEntry) lockOnuKVStoreMutex() {
750 oo.onuKVStoreMutex.Lock()
751}
752
753func (oo *OnuDeviceEntry) unlockOnuKVStoreMutex() {
754 oo.onuKVStoreMutex.Unlock()
755}