blob: dcc47b0683f3514df9a09d6c9c8d312ed734fdc9 [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"
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 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000153 databaseClass func(context.Context) error
Himani Chawla4d908332020-08-31 12:30:20 +0530154 //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
dbainbri4d3a0dc2020-12-02 00:33:42 +0000181func (oo *AdapterFsm) logFsmStateChange(ctx context.Context, e *fsm.Event) {
182 logger.Debugw(ctx, "FSM state change", log.Fields{"device-id": oo.deviceID, "FSM name": oo.fsmName,
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000183 "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)
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +0000192const onuDataMeID = 0
Himani Chawla6d2ae152020-09-02 13:11:20 +0530193const onugMeID = 0
194const onu2gMeID = 0
195const ipHostConfigDataMeID = 1
196const onugSerialNumberLen = 8
197const omciMacAddressLen = 6
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000198
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000199const cEmptyMacAddrString = "000000000000"
200const cEmptySerialNumberString = "0000000000000000"
201
Himani Chawla6d2ae152020-09-02 13:11:20 +0530202type swImages struct {
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000203 version string
204 isActive uint8
205}
206
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000207type uniPersConfig struct {
208 PersUniID uint8 `json:"uni_id"`
Girish Gowdra041dcb32020-11-16 16:54:30 -0800209 PersTpPathMap map[uint8]string `json:"PersTpPathMap"` // tp-id to tp-path map
210 PersFlowParams []uniVlanFlowParams `json:"flow_params"` //as defined in omci_ani_config.go
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000211}
212
213type onuPersistentData struct {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000214 PersOnuID uint32 `json:"onu_id"`
215 PersIntfID uint32 `json:"intf_id"`
216 PersSnr string `json:"serial_number"`
217 PersAdminState string `json:"admin_state"`
218 PersOperState string `json:"oper_state"`
219 PersUniUnlockDone bool `json:"uni_unlock_done"`
220 PersUniDisableDone bool `json:"uni_disable_done"`
221 PersUniConfig []uniPersConfig `json:"uni_config"`
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000222}
223
Himani Chawla6d2ae152020-09-02 13:11:20 +0530224// OnuDeviceEntry - ONU device info and FSM events.
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000225type OnuDeviceEntry struct {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000226 deviceID string
227 baseDeviceHandler *deviceHandler
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000228 pOpenOnuAc *OpenONUAC
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000229 coreProxy adapterif.CoreProxy
230 adapterProxy adapterif.AdapterProxy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000231 PDevOmciCC *omciCC
232 pOnuDB *onuDeviceDB
233 mibTemplateKVStore *db.Backend
234 sOnuPersistentData onuPersistentData
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000235 mibTemplatePath string
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000236 onuKVStoreMutex sync.RWMutex
237 onuKVStore *db.Backend
238 onuKVStorePath string
239 onuKVStoreprocResult error //error indication of processing
240 chOnuKvProcessingStep chan uint8
241 vendorID string
242 serialNumber string
243 equipmentID string
244 swImages [secondSwImageMeID + 1]swImages
245 activeSwVersion string
246 macAddress string
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000247 //lockDeviceEntries sync.RWMutex
dbainbri4d3a0dc2020-12-02 00:33:42 +0000248 mibDbClass func(context.Context) error
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000249 supportedFsms OmciDeviceFsms
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000250 devState OnuDeviceEvent
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +0000251 // Audit and MDS
252 mibAuditDelay uint16
253 mibLastDbSync uint32
254 mibDataSyncAdpt uint8
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000255
256 // for mibUpload
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000257 pMibUploadFsm *AdapterFsm //could be handled dynamically and more general as pAdapterFsm - perhaps later
258 // for mibDownload
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000259 pMibDownloadFsm *AdapterFsm //could be handled dynamically and more general as pAdapterFsm - perhaps later
260 //remark: general usage of pAdapterFsm would require generalization of commChan usage and internal event setting
261 // within the FSM event procedures
ozgecanetsiae11479f2020-07-06 09:44:47 +0300262 omciMessageReceived chan bool //seperate channel needed by DownloadFsm
263 omciRebootMessageReceivedChannel chan Message // channel needed by Reboot request
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000264}
265
Himani Chawla6d2ae152020-09-02 13:11:20 +0530266//newOnuDeviceEntry returns a new instance of a OnuDeviceEntry
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000267//mib_db (as well as not inluded alarm_db not really used in this code? VERIFY!!)
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000268func newOnuDeviceEntry(ctx context.Context, dh *deviceHandler) *OnuDeviceEntry {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000269 logger.Debugw(ctx, "init-onuDeviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000270 var onuDeviceEntry OnuDeviceEntry
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000271 onuDeviceEntry.deviceID = dh.deviceID
272 onuDeviceEntry.baseDeviceHandler = dh
273 onuDeviceEntry.pOpenOnuAc = dh.pOpenOnuAc
274 onuDeviceEntry.coreProxy = dh.coreProxy
275 onuDeviceEntry.adapterProxy = dh.AdapterProxy
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000276 onuDeviceEntry.devState = DeviceStatusInit
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000277 onuDeviceEntry.sOnuPersistentData.PersUniConfig = make([]uniPersConfig, 0)
278 onuDeviceEntry.chOnuKvProcessingStep = make(chan uint8)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300279 onuDeviceEntry.omciRebootMessageReceivedChannel = make(chan Message, 2048)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000280 //openomciagent.lockDeviceHandlersMap = sync.RWMutex{}
281 //OMCI related databases are on a per-agent basis. State machines and tasks
282 //are per ONU Vendor
283 //
284 // MIB Synchronization Database - possible overloading from arguments
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000285 if dh.pOpenOnuAc.pSupportedFsms != nil {
286 onuDeviceEntry.supportedFsms = *dh.pOpenOnuAc.pSupportedFsms
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000287 } else {
288 //var mibSyncFsm = NewMibSynchronizer()
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000289 // use some internaö defaults, if not defined from outside
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000290 onuDeviceEntry.supportedFsms = OmciDeviceFsms{
291 "mib-synchronizer": {
292 //mibSyncFsm, // Implements the MIB synchronization state machine
Himani Chawla6d2ae152020-09-02 13:11:20 +0530293 onuDeviceEntry.mibDbVolatileDict, // Implements volatile ME MIB database
Himani Chawla4d908332020-08-31 12:30:20 +0530294 //true, // Advertise events on OpenOMCI event bus
295 60, // Time to wait between MIB audits. 0 to disable audits.
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000296 // map[string]func() error{
297 // "mib-upload": onuDeviceEntry.MibUploadTask,
298 // "mib-template": onuDeviceEntry.MibTemplateTask,
299 // "get-mds": onuDeviceEntry.GetMdsTask,
300 // "mib-audit": onuDeviceEntry.GetMdsTask,
301 // "mib-resync": onuDeviceEntry.MibResyncTask,
302 // "mib-reconcile": onuDeviceEntry.MibReconcileTask,
303 // },
304 },
305 }
306 }
307 onuDeviceEntry.mibDbClass = onuDeviceEntry.supportedFsms["mib-synchronizer"].databaseClass
dbainbri4d3a0dc2020-12-02 00:33:42 +0000308 logger.Debug(ctx, "access2mibDbClass")
309 go onuDeviceEntry.mibDbClass(ctx)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000310 onuDeviceEntry.mibAuditDelay = onuDeviceEntry.supportedFsms["mib-synchronizer"].auditDelay
dbainbri4d3a0dc2020-12-02 00:33:42 +0000311 logger.Debugw(ctx, "MibAudit is set to", log.Fields{"Delay": onuDeviceEntry.mibAuditDelay})
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +0000312 onuDeviceEntry.mibLastDbSync = 0
313 onuDeviceEntry.mibDataSyncAdpt = 0
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000314
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000315 // Omci related Mib upload sync state machine
316 mibUploadChan := make(chan Message, 2048)
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000317 onuDeviceEntry.pMibUploadFsm = NewAdapterFsm("MibUpload", dh.deviceID, mibUploadChan)
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000318 onuDeviceEntry.pMibUploadFsm.pFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000319 ulStDisabled,
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000320 fsm.Events{
321
mpagenko1cc3cb42020-07-27 15:24:38 +0000322 {Name: ulEvStart, Src: []string{ulStDisabled}, Dst: ulStStarting},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000323
mpagenko1cc3cb42020-07-27 15:24:38 +0000324 {Name: ulEvResetMib, Src: []string{ulStStarting}, Dst: ulStResettingMib},
325 {Name: ulEvGetVendorAndSerial, Src: []string{ulStResettingMib}, Dst: ulStGettingVendorAndSerial},
Himani Chawla4d908332020-08-31 12:30:20 +0530326 {Name: ulEvGetEquipmentID, Src: []string{ulStGettingVendorAndSerial}, Dst: ulStGettingEquipmentID},
327 {Name: ulEvGetFirstSwVersion, Src: []string{ulStGettingEquipmentID}, Dst: ulStGettingFirstSwVersion},
mpagenko1cc3cb42020-07-27 15:24:38 +0000328 {Name: ulEvGetSecondSwVersion, Src: []string{ulStGettingFirstSwVersion}, Dst: ulStGettingSecondSwVersion},
329 {Name: ulEvGetMacAddress, Src: []string{ulStGettingSecondSwVersion}, Dst: ulStGettingMacAddress},
330 {Name: ulEvGetMibTemplate, Src: []string{ulStGettingMacAddress}, Dst: ulStGettingMibTemplate},
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000331
mpagenko1cc3cb42020-07-27 15:24:38 +0000332 {Name: ulEvUploadMib, Src: []string{ulStGettingMibTemplate}, Dst: ulStUploading},
333 {Name: ulEvExamineMds, Src: []string{ulStStarting}, Dst: ulStExaminingMds},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000334
mpagenko1cc3cb42020-07-27 15:24:38 +0000335 {Name: ulEvSuccess, Src: []string{ulStGettingMibTemplate}, Dst: ulStInSync},
336 {Name: ulEvSuccess, Src: []string{ulStUploading}, Dst: ulStInSync},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000337
mpagenko1cc3cb42020-07-27 15:24:38 +0000338 {Name: ulEvSuccess, Src: []string{ulStExaminingMds}, Dst: ulStInSync},
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +0000339 // TODO: As long as mib-resynchronizing is not implemented, failed MDS-examination triggers
340 // mib-reset and new provisioning at this point
341 //{Name: ulEvMismatch, Src: []string{ulStExaminingMds}, Dst: ulStResynchronizing},
342 {Name: ulEvMismatch, Src: []string{ulStExaminingMds}, Dst: ulStResettingMib},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000343
mpagenko1cc3cb42020-07-27 15:24:38 +0000344 {Name: ulEvAuditMib, Src: []string{ulStInSync}, Dst: ulStAuditing},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000345
mpagenko1cc3cb42020-07-27 15:24:38 +0000346 {Name: ulEvSuccess, Src: []string{ulStOutOfSync}, Dst: ulStInSync},
347 {Name: ulEvAuditMib, Src: []string{ulStOutOfSync}, Dst: ulStAuditing},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000348
mpagenko1cc3cb42020-07-27 15:24:38 +0000349 {Name: ulEvSuccess, Src: []string{ulStAuditing}, Dst: ulStInSync},
350 {Name: ulEvMismatch, Src: []string{ulStAuditing}, Dst: ulStResynchronizing},
351 {Name: ulEvForceResync, Src: []string{ulStAuditing}, Dst: ulStResynchronizing},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000352
mpagenko1cc3cb42020-07-27 15:24:38 +0000353 {Name: ulEvSuccess, Src: []string{ulStResynchronizing}, Dst: ulStInSync},
354 {Name: ulEvDiffsFound, Src: []string{ulStResynchronizing}, Dst: ulStOutOfSync},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000355
Himani Chawla4d908332020-08-31 12:30:20 +0530356 {Name: ulEvTimeout, Src: []string{ulStResettingMib, ulStGettingVendorAndSerial, ulStGettingEquipmentID, ulStGettingFirstSwVersion,
mpagenko1cc3cb42020-07-27 15:24:38 +0000357 ulStGettingSecondSwVersion, ulStGettingMacAddress, ulStGettingMibTemplate, ulStUploading, ulStResynchronizing, ulStExaminingMds,
358 ulStInSync, ulStOutOfSync, ulStAuditing}, Dst: ulStStarting},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000359
Himani Chawla4d908332020-08-31 12:30:20 +0530360 {Name: ulEvStop, Src: []string{ulStStarting, ulStResettingMib, ulStGettingVendorAndSerial, ulStGettingEquipmentID, ulStGettingFirstSwVersion,
mpagenko1cc3cb42020-07-27 15:24:38 +0000361 ulStGettingSecondSwVersion, ulStGettingMacAddress, ulStGettingMibTemplate, ulStUploading, ulStResynchronizing, ulStExaminingMds,
362 ulStInSync, ulStOutOfSync, ulStAuditing}, Dst: ulStDisabled},
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000363 },
364
365 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000366 "enter_state": func(e *fsm.Event) { onuDeviceEntry.pMibUploadFsm.logFsmStateChange(ctx, e) },
367 "enter_" + ulStStarting: func(e *fsm.Event) { onuDeviceEntry.enterStartingState(ctx, e) },
368 "enter_" + ulStResettingMib: func(e *fsm.Event) { onuDeviceEntry.enterResettingMibState(ctx, e) },
369 "enter_" + ulStGettingVendorAndSerial: func(e *fsm.Event) { onuDeviceEntry.enterGettingVendorAndSerialState(ctx, e) },
370 "enter_" + ulStGettingEquipmentID: func(e *fsm.Event) { onuDeviceEntry.enterGettingEquipmentIDState(ctx, e) },
371 "enter_" + ulStGettingFirstSwVersion: func(e *fsm.Event) { onuDeviceEntry.enterGettingFirstSwVersionState(ctx, e) },
372 "enter_" + ulStGettingSecondSwVersion: func(e *fsm.Event) { onuDeviceEntry.enterGettingSecondSwVersionState(ctx, e) },
373 "enter_" + ulStGettingMacAddress: func(e *fsm.Event) { onuDeviceEntry.enterGettingMacAddressState(ctx, e) },
374 "enter_" + ulStGettingMibTemplate: func(e *fsm.Event) { onuDeviceEntry.enterGettingMibTemplate(ctx, e) },
375 "enter_" + ulStUploading: func(e *fsm.Event) { onuDeviceEntry.enterUploadingState(ctx, e) },
376 "enter_" + ulStExaminingMds: func(e *fsm.Event) { onuDeviceEntry.enterExaminingMdsState(ctx, e) },
377 "enter_" + ulStResynchronizing: func(e *fsm.Event) { onuDeviceEntry.enterResynchronizingState(ctx, e) },
378 "enter_" + ulStAuditing: func(e *fsm.Event) { onuDeviceEntry.enterAuditingState(ctx, e) },
379 "enter_" + ulStOutOfSync: func(e *fsm.Event) { onuDeviceEntry.enterOutOfSyncState(ctx, e) },
380 "enter_" + ulStInSync: func(e *fsm.Event) { onuDeviceEntry.enterInSyncState(ctx, e) },
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000381 },
382 )
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000383 // Omci related Mib download state machine
384 mibDownloadChan := make(chan Message, 2048)
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000385 onuDeviceEntry.pMibDownloadFsm = NewAdapterFsm("MibDownload", dh.deviceID, mibDownloadChan)
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000386 onuDeviceEntry.pMibDownloadFsm.pFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000387 dlStDisabled,
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000388 fsm.Events{
389
mpagenko1cc3cb42020-07-27 15:24:38 +0000390 {Name: dlEvStart, Src: []string{dlStDisabled}, Dst: dlStStarting},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000391
mpagenko1cc3cb42020-07-27 15:24:38 +0000392 {Name: dlEvCreateGal, Src: []string{dlStStarting}, Dst: dlStCreatingGal},
393 {Name: dlEvRxGalResp, Src: []string{dlStCreatingGal}, Dst: dlStSettingOnu2g},
394 {Name: dlEvRxOnu2gResp, Src: []string{dlStSettingOnu2g}, Dst: dlStBridgeInit},
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000395 // the bridge state is used for multi ME config for alle UNI related ports
396 // maybe such could be reflected in the state machine as well (port number parametrized)
397 // but that looks not straightforward here - so we keep it simple here for the beginning(?)
mpagenko1cc3cb42020-07-27 15:24:38 +0000398 {Name: dlEvRxBridgeResp, Src: []string{dlStBridgeInit}, Dst: dlStDownloaded},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000399
mpagenko1cc3cb42020-07-27 15:24:38 +0000400 {Name: dlEvTimeoutSimple, Src: []string{dlStCreatingGal, dlStSettingOnu2g}, Dst: dlStStarting},
401 {Name: dlEvTimeoutBridge, Src: []string{dlStBridgeInit}, Dst: dlStStarting},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000402
mpagenko1cc3cb42020-07-27 15:24:38 +0000403 {Name: dlEvReset, Src: []string{dlStStarting, dlStCreatingGal, dlStSettingOnu2g,
404 dlStBridgeInit, dlStDownloaded}, Dst: dlStResetting},
405 // exceptional treatment for all states except dlStResetting
406 {Name: dlEvRestart, Src: []string{dlStStarting, dlStCreatingGal, dlStSettingOnu2g,
407 dlStBridgeInit, dlStDownloaded, dlStResetting}, Dst: dlStDisabled},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000408 },
409
410 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000411 "enter_state": func(e *fsm.Event) { onuDeviceEntry.pMibDownloadFsm.logFsmStateChange(ctx, e) },
412 "enter_" + dlStStarting: func(e *fsm.Event) { onuDeviceEntry.enterDLStartingState(ctx, e) },
413 "enter_" + dlStCreatingGal: func(e *fsm.Event) { onuDeviceEntry.enterCreatingGalState(ctx, e) },
414 "enter_" + dlStSettingOnu2g: func(e *fsm.Event) { onuDeviceEntry.enterSettingOnu2gState(ctx, e) },
415 "enter_" + dlStBridgeInit: func(e *fsm.Event) { onuDeviceEntry.enterBridgeInitState(ctx, e) },
416 "enter_" + dlStDownloaded: func(e *fsm.Event) { onuDeviceEntry.enterDownloadedState(ctx, e) },
417 "enter_" + dlStResetting: func(e *fsm.Event) { onuDeviceEntry.enterResettingState(ctx, e) },
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000418 },
419 )
420 if onuDeviceEntry.pMibDownloadFsm == nil || onuDeviceEntry.pMibDownloadFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000421 logger.Errorw(ctx, "MibDownloadFsm could not be instantiated", log.Fields{"device-id": dh.deviceID})
Andrea Campanella6515c582020-10-05 11:25:00 +0200422 // TODO some specifc error treatment - or waiting for crash ?
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000423 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000424
dbainbri4d3a0dc2020-12-02 00:33:42 +0000425 onuDeviceEntry.mibTemplateKVStore = onuDeviceEntry.baseDeviceHandler.setBackend(ctx, cBasePathMibTemplateKvStore)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000426 if onuDeviceEntry.mibTemplateKVStore == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000427 logger.Errorw(ctx, "Can't access mibTemplateKVStore - no backend connection to service",
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000428 log.Fields{"device-id": dh.deviceID, "service": cBasePathMibTemplateKvStore})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000429 }
430
431 onuDeviceEntry.onuKVStorePath = onuDeviceEntry.deviceID
Matteo Scandolof1f39a72020-11-24 12:08:11 -0800432 baseKvStorePath := fmt.Sprintf(cBasePathOnuKVStore, dh.pOpenOnuAc.cm.Backend.PathPrefix)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000433 onuDeviceEntry.onuKVStore = onuDeviceEntry.baseDeviceHandler.setBackend(ctx, baseKvStorePath)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000434 if onuDeviceEntry.onuKVStore == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000435 logger.Errorw(ctx, "Can't access onuKVStore - no backend connection to service",
Matteo Scandolof1f39a72020-11-24 12:08:11 -0800436 log.Fields{"device-id": dh.deviceID, "service": baseKvStorePath})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000437 }
438
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000439 // Alarm Synchronization Database
440 //self._alarm_db = None
441 //self._alarm_database_cls = support_classes['alarm-synchronizer']['database']
442 return &onuDeviceEntry
443}
444
Himani Chawla6d2ae152020-09-02 13:11:20 +0530445//start starts (logs) the omci agent
446func (oo *OnuDeviceEntry) start(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000447 logger.Debugw(ctx, "OnuDeviceEntry-starting", log.Fields{"for device-id": oo.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000448 if oo.PDevOmciCC == nil {
mpagenko900ee4b2020-10-12 11:56:34 +0000449 oo.PDevOmciCC = newOmciCC(ctx, oo, oo.deviceID, oo.baseDeviceHandler,
450 oo.coreProxy, oo.adapterProxy)
451 if oo.PDevOmciCC == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000452 logger.Errorw(ctx, "Could not create devOmciCc - abort", log.Fields{"for device-id": oo.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +0000453 return fmt.Errorf("could not create devOmciCc %s", oo.deviceID)
454 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000455 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000456 return nil
457}
458
mpagenko900ee4b2020-10-12 11:56:34 +0000459//stop stops/resets the omciCC
460func (oo *OnuDeviceEntry) stop(ctx context.Context, abResetOmciCC bool) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000461 logger.Debugw(ctx, "OnuDeviceEntry-stopping", log.Fields{"for device-id": oo.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +0000462 if abResetOmciCC && (oo.PDevOmciCC != nil) {
463 _ = oo.PDevOmciCC.stop(ctx)
464 }
465 //to allow for all event notifications again when re-using the device and omciCC
466 oo.devState = DeviceStatusInit
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000467 return nil
468}
469
Himani Chawla6d2ae152020-09-02 13:11:20 +0530470func (oo *OnuDeviceEntry) reboot(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000471 logger.Debugw(ctx, "OnuDeviceEntry-rebooting", log.Fields{"for device-id": oo.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +0000472 if oo.PDevOmciCC != nil {
473 if err := oo.PDevOmciCC.sendReboot(ctx, ConstDefaultOmciTimeout, true, oo.omciRebootMessageReceivedChannel); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000474 logger.Errorw(ctx, "onu didn't reboot", log.Fields{"for device-id": oo.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +0000475 return err
476 }
ozgecanetsiae11479f2020-07-06 09:44:47 +0300477 }
ozgecanetsiae11479f2020-07-06 09:44:47 +0300478 return nil
479}
480
dbainbri4d3a0dc2020-12-02 00:33:42 +0000481func (oo *OnuDeviceEntry) waitForRebootResponse(ctx context.Context, responseChannel chan Message) error {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300482 select {
483 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 +0000484 logger.Warnw(ctx, "Reboot timeout", log.Fields{"for device-id": oo.deviceID})
Andrea Campanella6515c582020-10-05 11:25:00 +0200485 return fmt.Errorf("rebootTimeout")
ozgecanetsiae11479f2020-07-06 09:44:47 +0300486 case data := <-responseChannel:
487 switch data.Data.(OmciMessage).OmciMsg.MessageType {
488 case omci.RebootResponseType:
489 {
490 msgLayer := (*data.Data.(OmciMessage).OmciPacket).Layer(omci.LayerTypeRebootResponse)
491 if msgLayer == nil {
Andrea Campanella6515c582020-10-05 11:25:00 +0200492 return fmt.Errorf("omci Msg layer could not be detected for RebootResponseType")
ozgecanetsiae11479f2020-07-06 09:44:47 +0300493 }
Andrea Campanellabef4e542020-10-22 11:01:28 +0200494 msgObj, msgOk := msgLayer.(*omci.RebootResponse)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300495 if !msgOk {
Andrea Campanella6515c582020-10-05 11:25:00 +0200496 return fmt.Errorf("omci Msg layer could not be assigned for RebootResponseType %s", oo.deviceID)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300497 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000498 logger.Debugw(ctx, "RebootResponse data", log.Fields{"device-id": oo.deviceID, "data-fields": msgObj})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300499 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000500 logger.Errorw(ctx, "Omci RebootResponse result error", log.Fields{"device-id": oo.deviceID, "Error": msgObj.Result})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300501 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
Andrea Campanellabef4e542020-10-22 11:01:28 +0200502 return fmt.Errorf("omci RebootResponse result error indication %s for device %s",
Andrea Campanella6515c582020-10-05 11:25:00 +0200503 msgObj.Result, oo.deviceID)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300504 }
505 return nil
506 }
507 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000508 logger.Warnw(ctx, "Reboot response message type error", log.Fields{"for device-id": oo.deviceID})
Andrea Campanella6515c582020-10-05 11:25:00 +0200509 return fmt.Errorf("unexpected OmciResponse type received %s", oo.deviceID)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300510 }
511}
512
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000513//Relay the InSync message via Handler to Rw core - Status update
dbainbri4d3a0dc2020-12-02 00:33:42 +0000514func (oo *OnuDeviceEntry) transferSystemEvent(ctx context.Context, devEvent OnuDeviceEvent) {
515 logger.Debugw(ctx, "relaying system-event", log.Fields{"Event": devEvent})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000516 // decouple the handler transfer from further processing here
517 // TODO!!! check if really no synch is required within the system e.g. to ensure following steps ..
Himani Chawla26e555c2020-08-31 12:30:20 +0530518 if devEvent == MibDatabaseSync {
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000519 if oo.devState < MibDatabaseSync { //devState has not been synced yet
520 oo.devState = MibDatabaseSync
dbainbri4d3a0dc2020-12-02 00:33:42 +0000521 go oo.baseDeviceHandler.deviceProcStatusUpdate(ctx, devEvent)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000522 //TODO!!! device control: next step: start MIB capability verification from here ?!!!
523 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000524 logger.Debugw(ctx, "mibinsync-event in some already synced state - ignored", log.Fields{"state": oo.devState})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000525 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530526 } else if devEvent == MibDownloadDone {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000527 if oo.devState < MibDownloadDone { //devState has not been synced yet
528 oo.devState = MibDownloadDone
dbainbri4d3a0dc2020-12-02 00:33:42 +0000529 go oo.baseDeviceHandler.deviceProcStatusUpdate(ctx, devEvent)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000530 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000531 logger.Debugw(ctx, "mibdownloaddone-event was already seen - ignored", log.Fields{"state": oo.devState})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000532 }
533 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000534 logger.Warnw(ctx, "device-event not yet handled", log.Fields{"state": devEvent})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000535 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000536}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000537
538func (oo *OnuDeviceEntry) restoreDataFromOnuKvStore(ctx context.Context) error {
539 if oo.onuKVStore == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000540 logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000541 return fmt.Errorf(fmt.Sprintf("onuKVStore-not-set-abort-%s", oo.deviceID))
542 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000543 oo.sOnuPersistentData = onuPersistentData{0, 0, "", "", "", false, false, make([]uniPersConfig, 0)}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000544 Value, err := oo.onuKVStore.Get(ctx, oo.onuKVStorePath)
545 if err == nil {
546 if Value != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000547 logger.Debugw(ctx, "ONU-data read",
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000548 log.Fields{"Key": Value.Key, "device-id": oo.deviceID})
549 tmpBytes, _ := kvstore.ToByte(Value.Value)
550
551 if err = json.Unmarshal(tmpBytes, &oo.sOnuPersistentData); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000552 logger.Errorw(ctx, "unable to unmarshal ONU-data", log.Fields{"error": err, "device-id": oo.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000553 return fmt.Errorf(fmt.Sprintf("unable-to-unmarshal-ONU-data-%s", oo.deviceID))
554 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000555 logger.Debugw(ctx, "ONU-data", log.Fields{"sOnuPersistentData": oo.sOnuPersistentData,
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000556 "device-id": oo.deviceID})
557 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000558 logger.Debugw(ctx, "no ONU-data found", log.Fields{"path": oo.onuKVStorePath, "device-id": oo.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000559 return fmt.Errorf("no-ONU-data-found")
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000560 }
561 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000562 logger.Errorw(ctx, "unable to read from KVstore", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000563 return fmt.Errorf(fmt.Sprintf("unable-to-read-from-KVstore-%s", oo.deviceID))
564 }
565 return nil
566}
567
568func (oo *OnuDeviceEntry) deleteDataFromOnuKvStore(ctx context.Context, wg *sync.WaitGroup) {
569 defer wg.Done()
570
571 if oo.onuKVStore == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000572 logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000573 oo.onuKVStoreprocResult = errors.New("onu-data delete aborted: onuKVStore not set")
574 return
575 }
576 var processingStep uint8 = 1 // used to synchronize the different processing steps with chOnuKvProcessingStep
577 go oo.deletePersistentData(ctx, processingStep)
578 if !oo.waitForTimeoutOrCompletion(ctx, oo.chOnuKvProcessingStep, processingStep) {
579 //timeout or error detected
dbainbri4d3a0dc2020-12-02 00:33:42 +0000580 logger.Debugw(ctx, "ONU-data not deleted - abort", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000581 oo.onuKVStoreprocResult = errors.New("onu-data delete aborted: during kv-access")
582 return
583 }
584}
585
586func (oo *OnuDeviceEntry) deletePersistentData(ctx context.Context, aProcessingStep uint8) {
587
dbainbri4d3a0dc2020-12-02 00:33:42 +0000588 logger.Debugw(ctx, "delete and clear internal persistency data", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000589 oo.sOnuPersistentData.PersUniConfig = nil //releasing all UniConfig entries to garbage collector
590 oo.sOnuPersistentData = onuPersistentData{0, 0, "", "", "", false, false, make([]uniPersConfig, 0)} //default entry
mpagenko2418ab02020-11-12 12:58:06 +0000591
dbainbri4d3a0dc2020-12-02 00:33:42 +0000592 logger.Debugw(ctx, "delete ONU-data from KVStore", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000593 err := oo.onuKVStore.Delete(ctx, oo.onuKVStorePath)
594 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000595 logger.Errorw(ctx, "unable to delete in KVstore", log.Fields{"device-id": oo.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000596 oo.chOnuKvProcessingStep <- 0 //error indication
597 return
598 }
599 oo.chOnuKvProcessingStep <- aProcessingStep //done
600}
601
602func (oo *OnuDeviceEntry) updateOnuKvStore(ctx context.Context, wg *sync.WaitGroup) {
603 defer wg.Done()
604
605 if oo.onuKVStore == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000606 logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000607 oo.onuKVStoreprocResult = errors.New("onu-data update aborted: onuKVStore not set")
608 return
609 }
610 var processingStep uint8 = 1 // used to synchronize the different processing steps with chOnuKvProcessingStep
611 go oo.storeDataInOnuKvStore(ctx, processingStep)
612 if !oo.waitForTimeoutOrCompletion(ctx, oo.chOnuKvProcessingStep, processingStep) {
613 //timeout or error detected
dbainbri4d3a0dc2020-12-02 00:33:42 +0000614 logger.Debugw(ctx, "ONU-data not written - abort", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000615 oo.onuKVStoreprocResult = errors.New("onu-data update aborted: during writing process")
616 return
617 }
618}
619
620func (oo *OnuDeviceEntry) storeDataInOnuKvStore(ctx context.Context, aProcessingStep uint8) {
621
622 //assign values which are not already present when newOnuDeviceEntry() is called
623 oo.sOnuPersistentData.PersOnuID = oo.baseDeviceHandler.pOnuIndication.OnuId
624 oo.sOnuPersistentData.PersIntfID = oo.baseDeviceHandler.pOnuIndication.IntfId
625 oo.sOnuPersistentData.PersSnr = oo.baseDeviceHandler.pOnuOmciDevice.serialNumber
626 //TODO: verify usage of these values during restart UC
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000627 oo.sOnuPersistentData.PersAdminState = oo.baseDeviceHandler.pOnuIndication.AdminState
628 oo.sOnuPersistentData.PersOperState = oo.baseDeviceHandler.pOnuIndication.OperState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000629 logger.Debugw(ctx, "Update ONU-data in KVStore", log.Fields{"device-id": oo.deviceID, "sOnuPersistentData": oo.sOnuPersistentData})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000630
631 Value, err := json.Marshal(oo.sOnuPersistentData)
632 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000633 logger.Errorw(ctx, "unable to marshal ONU-data", log.Fields{"sOnuPersistentData": oo.sOnuPersistentData,
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000634 "device-id": oo.deviceID, "err": err})
635 oo.chOnuKvProcessingStep <- 0 //error indication
636 return
637 }
638 err = oo.onuKVStore.Put(ctx, oo.onuKVStorePath, Value)
639 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000640 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 +0000641 oo.chOnuKvProcessingStep <- 0 //error indication
642 return
643 }
644 oo.chOnuKvProcessingStep <- aProcessingStep //done
645}
646
dbainbri4d3a0dc2020-12-02 00:33:42 +0000647func (oo *OnuDeviceEntry) updateOnuUniTpPath(ctx context.Context, aUniID uint8, aTpID uint8, aPathString string) bool {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000648 /* within some specific InterAdapter processing request write/read access to data is ensured to be sequentially,
649 as also the complete sequence is ensured to 'run to completion' before some new request is accepted
650 no specific concurrency protection to sOnuPersistentData is required here
651 */
652 for k, v := range oo.sOnuPersistentData.PersUniConfig {
653 if v.PersUniID == aUniID {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000654 logger.Debugw(ctx, "PersUniConfig-entry already exists", log.Fields{"device-id": oo.deviceID, "uniID": aUniID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800655 existingPath, ok := oo.sOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID]
656 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000657 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 -0800658 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000659 if existingPath != aPathString {
660 if aPathString == "" {
661 //existing entry to be deleted
dbainbri4d3a0dc2020-12-02 00:33:42 +0000662 logger.Debugw(ctx, "UniTp delete path value", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800663 oo.sOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID] = ""
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000664 } else {
665 //existing entry to be modified
dbainbri4d3a0dc2020-12-02 00:33:42 +0000666 logger.Debugw(ctx, "UniTp modify path value", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800667 oo.sOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID] = aPathString
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000668 }
669 return true
670 }
671 //entry already exists
mpagenkofc4f56e2020-11-04 17:17:49 +0000672 if aPathString == "" {
673 //no active TechProfile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000674 logger.Debugw(ctx, "UniTp path has already been removed - no AniSide config to be removed", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000675 "device-id": oo.deviceID, "uniID": aUniID})
676 // attention 201105: this block is at the moment entered for each of subsequent GemPortDeletes and TContDelete
677 // as the path is already cleared with the first GemPort - this will probably change with the upcoming real
678 // TechProfile removal (still TODO), but anyway the reasonUpdate initiated here should not harm overall behavior
dbainbri4d3a0dc2020-12-02 00:33:42 +0000679 go oo.baseDeviceHandler.deviceProcStatusUpdate(ctx, OmciAniResourceRemoved)
mpagenkofc4f56e2020-11-04 17:17:49 +0000680 // no flow config pending on 'remove' so far
681 } else {
682 //the given TechProfile already exists and is assumed to be active - update devReason as if the config has been done here
683 //was needed e.g. in voltha POD Tests:Validate authentication on a disabled ONU
684 // (as here the TechProfile has not been removed with the disable-device before the new enable-device)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000685 logger.Debugw(ctx, "UniTp path already exists - TechProfile supposed to be active", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000686 "device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
687 //no deviceReason update (deviceProcStatusUpdate) here to ensure 'omci_flows_pushed' state within disable/enable procedure of ATT scenario
688 // (during which the flows are removed/re-assigned but the techProf is left active)
689 //and as the TechProfile is regarded as active we have to verify, if some flow configuration still waits on it
690 // (should not be the case, but should not harm or be more robust ...)
mpagenko2418ab02020-11-12 12:58:06 +0000691 // and to be sure, that for some reason the corresponding TpDelete was lost somewhere in history
692 // we also reset a possibly outstanding delete request - repeated TpConfig is regarded as valid for waiting flow config
693 if oo.baseDeviceHandler.pOnuTP != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -0800694 oo.baseDeviceHandler.pOnuTP.setProfileToDelete(aUniID, aTpID, false)
mpagenko2418ab02020-11-12 12:58:06 +0000695 }
mpagenko551a4d42020-12-08 18:09:20 +0000696 go oo.baseDeviceHandler.VerifyVlanConfigRequest(ctx, aUniID, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +0000697 }
698 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 +0000699 }
700 }
701 //no entry exists for uniId
702
703 if aPathString == "" {
704 //delete request in non-existing state , accept as no change
dbainbri4d3a0dc2020-12-02 00:33:42 +0000705 logger.Debugw(ctx, "UniTp path already removed", log.Fields{"device-id": oo.deviceID, "uniID": aUniID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000706 return false
707 }
708 //new entry to be created
dbainbri4d3a0dc2020-12-02 00:33:42 +0000709 logger.Debugw(ctx, "New UniTp path set", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800710 perSubTpPathMap := make(map[uint8]string)
711 perSubTpPathMap[aTpID] = aPathString
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000712 oo.sOnuPersistentData.PersUniConfig =
Girish Gowdra041dcb32020-11-16 16:54:30 -0800713 append(oo.sOnuPersistentData.PersUniConfig, uniPersConfig{PersUniID: aUniID, PersTpPathMap: perSubTpPathMap, PersFlowParams: make([]uniVlanFlowParams, 0)})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000714 return true
715}
716
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000717func (oo *OnuDeviceEntry) updateOnuUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) {
718
719 for k, v := range oo.sOnuPersistentData.PersUniConfig {
720 if v.PersUniID == aUniID {
721 oo.sOnuPersistentData.PersUniConfig[k].PersFlowParams = make([]uniVlanFlowParams, len(*aUniVlanFlowParams))
722 copy(oo.sOnuPersistentData.PersUniConfig[k].PersFlowParams, *aUniVlanFlowParams)
723 return
724 }
725 }
726 //flow update was faster than tp-config - create PersUniConfig-entry
Girish Gowdra041dcb32020-11-16 16:54:30 -0800727 tmpConfig := uniPersConfig{PersUniID: aUniID, PersTpPathMap: make(map[uint8]string), PersFlowParams: make([]uniVlanFlowParams, len(*aUniVlanFlowParams))}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000728 copy(tmpConfig.PersFlowParams, *aUniVlanFlowParams)
729 oo.sOnuPersistentData.PersUniConfig = append(oo.sOnuPersistentData.PersUniConfig, tmpConfig)
730}
731
732func (oo *OnuDeviceEntry) waitForTimeoutOrCompletion(
733 ctx context.Context, aChOnuProcessingStep <-chan uint8, aProcessingStep uint8) bool {
734 select {
735 case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +0000736 logger.Warnw(ctx, "processing not completed in-time!",
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000737 log.Fields{"device-id": oo.deviceID, "error": ctx.Err()})
738 return false
739 case rxStep := <-aChOnuProcessingStep:
740 if rxStep == aProcessingStep {
741 return true
742 }
743 //all other values are not accepted - including 0 for error indication
dbainbri4d3a0dc2020-12-02 00:33:42 +0000744 logger.Warnw(ctx, "Invalid processing step received: abort!",
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000745 log.Fields{"device-id": oo.deviceID,
746 "wantedStep": aProcessingStep, "haveStep": rxStep})
747 return false
748 }
749}
750
751func (oo *OnuDeviceEntry) resetKvProcessingErrorIndication() {
752 oo.onuKVStoreprocResult = nil
753}
754func (oo *OnuDeviceEntry) getKvProcessingErrorIndication() error {
755 return oo.onuKVStoreprocResult
756}
757
758func (oo *OnuDeviceEntry) lockOnuKVStoreMutex() {
759 oo.onuKVStoreMutex.Lock()
760}
761
762func (oo *OnuDeviceEntry) unlockOnuKVStoreMutex() {
763 oo.onuKVStoreMutex.Unlock()
764}
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +0000765
766func (oo *OnuDeviceEntry) incrementMibDataSync(ctx context.Context) {
767 if oo.mibDataSyncAdpt < 255 {
768 oo.mibDataSyncAdpt++
769 } else {
770 // per G.984 and G.988 overflow starts over at 1 given 0 is reserved for reset
771 oo.mibDataSyncAdpt = 1
772 }
773 logger.Debugf(ctx, "mibDataSync updated - mds: %d - device-id: %s", oo.mibDataSyncAdpt, oo.deviceID)
774}