blob: 59d32366c0b45611823ffd10e429e5b1d77f6b82 [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000022 "errors"
23 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000024 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000025 "sync"
26 "time"
27
28 "github.com/gogo/protobuf/proto"
29 "github.com/golang/protobuf/ptypes"
30 "github.com/looplab/fsm"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000031 me "github.com/opencord/omci-lib-go/generated"
dbainbri4d3a0dc2020-12-02 00:33:42 +000032 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/adapterif"
33 "github.com/opencord/voltha-lib-go/v4/pkg/db"
Himani Chawlac07fda02020-12-09 16:21:21 +053034 "github.com/opencord/voltha-lib-go/v4/pkg/events/eventif"
dbainbri4d3a0dc2020-12-02 00:33:42 +000035 flow "github.com/opencord/voltha-lib-go/v4/pkg/flows"
36 "github.com/opencord/voltha-lib-go/v4/pkg/log"
37 vc "github.com/opencord/voltha-protos/v4/go/common"
kesavandfdf77632021-01-26 23:40:33 -050038 "github.com/opencord/voltha-protos/v4/go/extension"
dbainbri4d3a0dc2020-12-02 00:33:42 +000039 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
40 "github.com/opencord/voltha-protos/v4/go/openflow_13"
41 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
42 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
43 oop "github.com/opencord/voltha-protos/v4/go/openolt"
44 "github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000045)
46
47/*
48// Constants for number of retries and for timeout
49const (
50 MaxRetry = 10
51 MaxTimeOutInMs = 500
52)
53*/
54
mpagenko1cc3cb42020-07-27 15:24:38 +000055const (
56 // events of Device FSM
57 devEvDeviceInit = "devEvDeviceInit"
58 devEvGrpcConnected = "devEvGrpcConnected"
59 devEvGrpcDisconnected = "devEvGrpcDisconnected"
60 devEvDeviceUpInd = "devEvDeviceUpInd"
61 devEvDeviceDownInd = "devEvDeviceDownInd"
62)
63const (
64 // states of Device FSM
65 devStNull = "devStNull"
66 devStDown = "devStDown"
67 devStInit = "devStInit"
68 devStConnected = "devStConnected"
69 devStUp = "devStUp"
70)
71
Holger Hildebrandt24d51952020-05-04 14:03:42 +000072//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
73const (
Himani Chawla4d908332020-08-31 12:30:20 +053074 pon = voltha.EventSubCategory_PON
75 //olt = voltha.EventSubCategory_OLT
76 //ont = voltha.EventSubCategory_ONT
77 //onu = voltha.EventSubCategory_ONU
78 //nni = voltha.EventSubCategory_NNI
79 //service = voltha.EventCategory_SERVICE
80 //security = voltha.EventCategory_SECURITY
81 equipment = voltha.EventCategory_EQUIPMENT
82 //processing = voltha.EventCategory_PROCESSING
83 //environment = voltha.EventCategory_ENVIRONMENT
84 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000085)
86
87const (
88 cEventObjectType = "ONU"
89)
90const (
91 cOnuActivatedEvent = "ONU_ACTIVATED"
92)
93
Holger Hildebrandt10d98192021-01-27 15:29:31 +000094type usedOmciConfigFsms int
95
96const (
97 cUploadFsm usedOmciConfigFsms = iota
98 cDownloadFsm
99 cUniLockFsm
100 cUniUnLockFsm
101 cAniConfigFsm
102 cUniVlanConfigFsm
Girish Gowdrae0140f02021-02-02 16:55:09 -0800103 cL2PmFsm
mpagenko80622a52021-02-09 16:53:23 +0000104 cOnuUpgradeFsm
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000105)
106
mpagenkof1fc3862021-02-16 10:09:52 +0000107type omciIdleCheckStruct struct {
108 omciIdleCheckFunc func(*deviceHandler, context.Context, usedOmciConfigFsms, string) bool
109 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000110}
111
mpagenkof1fc3862021-02-16 10:09:52 +0000112var fsmOmciIdleStateFuncMap = map[usedOmciConfigFsms]omciIdleCheckStruct{
113 cUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibUlFsmIdleState},
114 cDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibDlFsmIdleState},
115 cUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
116 cUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
117 cAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, cAniFsmIdleState},
118 cUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, cVlanFsmIdleState},
119 cL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cL2PmFsmIdleState},
mpagenko80622a52021-02-09 16:53:23 +0000120 cOnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cOnuUpgradeFsmIdleState},
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000121}
122
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000123const (
124 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000125 drUnset = 0
126 drActivatingOnu = 1
127 drStartingOpenomci = 2
128 drDiscoveryMibsyncComplete = 3
129 drInitialMibDownloaded = 4
130 drTechProfileConfigDownloadSuccess = 5
131 drOmciFlowsPushed = 6
132 drOmciAdminLock = 7
133 drOnuReenabled = 8
134 drStoppingOpenomci = 9
135 drRebooting = 10
136 drOmciFlowsDeleted = 11
137 drTechProfileConfigDeleteSuccess = 12
Maninder7961d722021-06-16 22:10:28 +0530138 drReconcileFailed = 13
139 drReconcileMaxTimeout = 14
140 drReconcileCanceled = 15
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000141)
142
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000143var deviceReasonMap = map[uint8]string{
144 drUnset: "unset",
145 drActivatingOnu: "activating-onu",
146 drStartingOpenomci: "starting-openomci",
147 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
148 drInitialMibDownloaded: "initial-mib-downloaded",
149 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
150 drOmciFlowsPushed: "omci-flows-pushed",
151 drOmciAdminLock: "omci-admin-lock",
152 drOnuReenabled: "onu-reenabled",
153 drStoppingOpenomci: "stopping-openomci",
154 drRebooting: "rebooting",
155 drOmciFlowsDeleted: "omci-flows-deleted",
156 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
Maninder7961d722021-06-16 22:10:28 +0530157 drReconcileFailed: "reconcile-failed",
158 drReconcileMaxTimeout: "reconcile-max-timeout",
159 drReconcileCanceled: "reconciling-canceled",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000160}
161
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000162const (
163 cNoReconciling = iota
164 cOnuConfigReconciling
165 cSkipOnuConfigReconciling
166)
167
Himani Chawla6d2ae152020-09-02 13:11:20 +0530168//deviceHandler will interact with the ONU ? device.
169type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000170 deviceID string
171 DeviceType string
172 adminState string
173 device *voltha.Device
174 logicalDeviceID string
175 ProxyAddressID string
176 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530177 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000178 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000179
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000180 coreProxy adapterif.CoreProxy
181 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530182 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000183
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800184 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800185
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000186 pOpenOnuAc *OpenONUAC
187 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530188 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000189 deviceEntrySet chan bool //channel for DeviceEntry set event
190 pOnuOmciDevice *OnuDeviceEntry
191 pOnuTP *onuUniTechProf
192 pOnuMetricsMgr *onuMetricsManager
193 pAlarmMgr *onuAlarmManager
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700194 pSelfTestHdlr *selfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000195 exitChannel chan int
196 lockDevice sync.RWMutex
197 pOnuIndication *oop.OnuIndication
198 deviceReason uint8
199 mutexDeviceReason sync.RWMutex
200 pLockStateFsm *lockStateFsm
201 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000202
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000203 //flowMgr *OpenOltFlowMgr
204 //eventMgr *OpenOltEventMgr
205 //resourceMgr *rsrcMgr.OpenOltResourceMgr
206
207 //discOnus sync.Map
208 //onus sync.Map
209 //portStats *OpenOltStatisticsMgr
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000210 collectorIsRunning bool
211 mutexCollectorFlag sync.RWMutex
212 stopCollector chan bool
213 alarmManagerIsRunning bool
214 mutextAlarmManagerFlag sync.RWMutex
215 stopAlarmManager chan bool
216 stopHeartbeatCheck chan bool
217 uniEntityMap map[uint32]*onuUniPort
218 mutexKvStoreContext sync.Mutex
219 lockVlanConfig sync.RWMutex
220 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
221 lockUpgradeFsm sync.RWMutex
222 pOnuUpradeFsm *OnuUpgradeFsm
223 reconciling uint8
224 mutexReconcilingFlag sync.RWMutex
225 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000226 reconcilingFlows bool
227 mutexReconcilingFlowsFlag sync.RWMutex
228 chReconcilingFlowsFinished chan bool //channel to indicate that reconciling of flows has been finished
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000229 mutexReadyForOmciConfig sync.RWMutex
230 readyForOmciConfig bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000231 deletionInProgress bool
232 mutexDeletionInProgressFlag sync.RWMutex
mpagenkoaa3afe92021-05-21 16:20:58 +0000233 upgradeSuccess bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000234}
235
Himani Chawla6d2ae152020-09-02 13:11:20 +0530236//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530237func newDeviceHandler(ctx context.Context, cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530238 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000239 dh.coreProxy = cp
240 dh.AdapterProxy = ap
241 dh.EventProxy = ep
242 cloned := (proto.Clone(device)).(*voltha.Device)
243 dh.deviceID = cloned.Id
244 dh.DeviceType = cloned.Type
245 dh.adminState = "up"
246 dh.device = cloned
247 dh.pOpenOnuAc = adapter
248 dh.exitChannel = make(chan int, 1)
249 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000250 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000251 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000252 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530253 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530254 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000255 dh.stopHeartbeatCheck = make(chan bool, 2)
256 //dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000257 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530258 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000259 dh.lockVlanConfig = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000260 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000261 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000262 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000263 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000264 dh.reconcilingFlows = false
265 dh.chReconcilingFlowsFinished = make(chan bool)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000266 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000267 dh.deletionInProgress = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000268
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800269 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
270 dh.pmConfigs = cloned.PmConfigs
271 } /* else {
272 // will be populated when onu_metrics_mananger is initialized.
273 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800274
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000275 // Device related state machine
276 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000277 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000278 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000279 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
280 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
281 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
282 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
283 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000284 },
285 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000286 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
287 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
288 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
289 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
290 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
291 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
292 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
293 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000294 },
295 )
mpagenkoaf801632020-07-03 10:00:42 +0000296
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297 return &dh
298}
299
Himani Chawla6d2ae152020-09-02 13:11:20 +0530300// start save the device to the data model
301func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000302 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000303 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000304 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000305}
306
Himani Chawla4d908332020-08-31 12:30:20 +0530307/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000308// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530309func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000310 logger.Debug("stopping-device-handler")
311 dh.exitChannel <- 1
312}
Himani Chawla4d908332020-08-31 12:30:20 +0530313*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000314
315// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530316// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000317
Girish Gowdrae0140f02021-02-02 16:55:09 -0800318//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530319func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000320 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000321
dbainbri4d3a0dc2020-12-02 00:33:42 +0000322 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000323 if dh.pDeviceStateFsm.Is(devStNull) {
324 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000325 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000326 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000327 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800328 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
329 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800330 // Now, set the initial PM configuration for that device
331 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
332 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
333 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800334 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000335 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000336 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000337 }
338
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000339}
340
mpagenko057889c2021-01-21 16:51:58 +0000341func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530342 msgBody := msg.GetBody()
343 omciMsg := &ic.InterAdapterOmciMessage{}
344 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000345 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530346 "device-id": dh.deviceID, "error": err})
347 return err
348 }
349
mpagenko80622a52021-02-09 16:53:23 +0000350 /* msg print moved symmetrically to omci_cc, if wanted here as additional debug, than perhaps only based on additional debug setting!
Himani Chawla26e555c2020-08-31 12:30:20 +0530351 //assuming omci message content is hex coded!
352 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000353 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530354 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000355 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000356 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530357 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000358 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000359 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000360 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000361 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"rxMsg": omciMsg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530362 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000363 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000364 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530365}
366
Himani Chawla6d2ae152020-09-02 13:11:20 +0530367func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000368 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530369 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000370
dbainbri4d3a0dc2020-12-02 00:33:42 +0000371 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000372
dbainbri4d3a0dc2020-12-02 00:33:42 +0000373 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000374 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000375 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000376 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
377 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530378 if dh.pOnuTP == nil {
379 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000380 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530381 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000382 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530383 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000384 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000385 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000386 "device-state": dh.getDeviceReasonString()})
387 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530388 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000389 //previous state test here was just this one, now extended for more states to reject the SetRequest:
390 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
391 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530392
393 msgBody := msg.GetBody()
394 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
395 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000396 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530397 "device-id": dh.deviceID, "error": err})
398 return err
399 }
400
401 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000402 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
403 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530404 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000405 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000406
407 if techProfMsg.UniId > 255 {
408 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
409 techProfMsg.UniId, dh.deviceID))
410 }
411 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800412 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
413 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000414 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800415 return err
416 }
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700417 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.Path, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000418
dbainbri4d3a0dc2020-12-02 00:33:42 +0000419 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700420 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.Path, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530421 // if there has been some change for some uni TechProfilePath
422 //in order to allow concurrent calls to other dh instances we do not wait for execution here
423 //but doing so we can not indicate problems to the caller (who does what with that then?)
424 //by now we just assume straightforward successful execution
425 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
426 // possible problems to the caller later autonomously
427
428 // deadline context to ensure completion of background routines waited for
429 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
Himani Chawlad96df182020-09-28 11:12:02 +0530430 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530431 dctx, cancel := context.WithDeadline(context.Background(), deadline)
432
Girish Gowdra041dcb32020-11-16 16:54:30 -0800433 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000434
Himani Chawla26e555c2020-08-31 12:30:20 +0530435 var wg sync.WaitGroup
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700436 wg.Add(1) // for the 1 go routine to finish
Himani Chawla26e555c2020-08-31 12:30:20 +0530437 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000438 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000439 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700440 if tpErr := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
441 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.deviceID, "err": tpErr, "tp-path": techProfMsg.Path})
442 return tpErr
443 }
444 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
445 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
446 pDevEntry.resetKvProcessingErrorIndication()
447 wg.Add(1) // for the 1 go routine to finish
448 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
449 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
450 if kvErr := pDevEntry.getKvProcessingErrorIndication(); kvErr != nil {
451 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.deviceID, "err": kvErr, "tp-path": techProfMsg.Path})
452 return kvErr
453 }
454 return nil
Himani Chawla26e555c2020-08-31 12:30:20 +0530455 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000456 // no change, nothing really to do - return success
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700457 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.Path, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530458 return nil
459}
460
Himani Chawla6d2ae152020-09-02 13:11:20 +0530461func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000462 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530463 msg *ic.InterAdapterMessage) error {
464
dbainbri4d3a0dc2020-12-02 00:33:42 +0000465 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000466
dbainbri4d3a0dc2020-12-02 00:33:42 +0000467 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000468 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000469 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000470 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
471 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530472 if dh.pOnuTP == nil {
473 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000474 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530475 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000476 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530477 }
478
479 msgBody := msg.GetBody()
480 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
481 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000482 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530483 "device-id": dh.deviceID, "error": err})
484 return err
485 }
486
487 //compare TECH_PROFILE_DOWNLOAD_REQUEST
488 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000489 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530490
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000491 if delGemPortMsg.UniId > 255 {
492 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
493 delGemPortMsg.UniId, dh.deviceID))
494 }
495 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800496 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
497 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000498 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": delGemPortMsg.TpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800499 return err
500 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530501
mpagenkofc4f56e2020-11-04 17:17:49 +0000502 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000503
mpagenkofc4f56e2020-11-04 17:17:49 +0000504 // deadline context to ensure completion of background routines waited for
505 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
506 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000507
Girish Gowdra041dcb32020-11-16 16:54:30 -0800508 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000509
mpagenkofc4f56e2020-11-04 17:17:49 +0000510 var wg sync.WaitGroup
511 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000512 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000513 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000514 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000515
Girish Gowdra041dcb32020-11-16 16:54:30 -0800516 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530517}
518
Himani Chawla6d2ae152020-09-02 13:11:20 +0530519func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000520 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530521 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000522
dbainbri4d3a0dc2020-12-02 00:33:42 +0000523 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000524
dbainbri4d3a0dc2020-12-02 00:33:42 +0000525 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000526 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000527 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000528 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
529 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530530 if dh.pOnuTP == nil {
531 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000532 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530533 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000534 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530535 }
536
537 msgBody := msg.GetBody()
538 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
539 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000540 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530541 "device-id": dh.deviceID, "error": err})
542 return err
543 }
544
545 //compare TECH_PROFILE_DOWNLOAD_REQUEST
546 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000547 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000548
549 if delTcontMsg.UniId > 255 {
550 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
551 delTcontMsg.UniId, dh.deviceID))
552 }
553 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800554 tpPath := delTcontMsg.TpPath
555 tpID, err := GetTpIDFromTpPath(tpPath)
556 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000557 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800558 return err
559 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000560
dbainbri4d3a0dc2020-12-02 00:33:42 +0000561 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700562 pDevEntry.freeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530563 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530564 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530565 dctx, cancel := context.WithDeadline(context.Background(), deadline)
566
Girish Gowdra041dcb32020-11-16 16:54:30 -0800567 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000568 pDevEntry.resetKvProcessingErrorIndication()
569
Himani Chawla26e555c2020-08-31 12:30:20 +0530570 var wg sync.WaitGroup
571 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000572 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530573 cResourceTcont, delTcontMsg.AllocId, &wg)
574 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000575 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
576 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000577
Girish Gowdra041dcb32020-11-16 16:54:30 -0800578 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530579 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530580 return nil
581}
582
Himani Chawla6d2ae152020-09-02 13:11:20 +0530583//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000584// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
585// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000586func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000587 msgID := msg.Header.Id
588 msgType := msg.Header.Type
589 fromTopic := msg.Header.FromTopic
590 toTopic := msg.Header.ToTopic
591 toDeviceID := msg.Header.ToDeviceId
592 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000593 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000594 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
595
596 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000597 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000598 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
599 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000600 {
mpagenko057889c2021-01-21 16:51:58 +0000601 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000602 }
mpagenkoaf801632020-07-03 10:00:42 +0000603 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
604 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000605 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000606 }
607 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
608 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000609 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000610
mpagenkoaf801632020-07-03 10:00:42 +0000611 }
612 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
613 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000614 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000615 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000616 default:
617 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000618 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000619 "msgType": msg.Header.Type, "device-id": dh.deviceID})
620 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000621 }
622 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000623}
624
mpagenkodff5dda2020-08-28 11:52:01 +0000625//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000626func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
627 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000628 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000629 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000630
mpagenko01e726e2020-10-23 09:45:29 +0000631 var retError error = nil
632 //Remove flows (always remove flows first - remove old and add new with same cookie may be part of the same request)
mpagenkodff5dda2020-08-28 11:52:01 +0000633 if apOfFlowChanges.ToRemove != nil {
634 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000635 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000636 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000637 "device-id": dh.deviceID})
638 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000639 continue
640 }
641 flowInPort := flow.GetInPort(flowItem)
642 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000643 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000644 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
645 continue
646 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000647 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000648 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000649 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000650 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000651 continue
652 } else {
653 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530654 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000655 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
656 loUniPort = uniPort
657 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000658 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000659 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
660 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
661 flowInPort, dh.deviceID)
662 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000663 }
664 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000665 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000666 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000667 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000668 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000669 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000670 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000671 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000672 log.Fields{"device-id": dh.deviceID, "error": err})
673 retError = err
674 continue
675 //return err
676 } else { // if last setting succeeds, overwrite possibly previously set error
677 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000678 }
679 }
680 }
681 }
mpagenko01e726e2020-10-23 09:45:29 +0000682 if apOfFlowChanges.ToAdd != nil {
683 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
684 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000685 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000686 "device-id": dh.deviceID})
687 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
688 continue
689 }
690 flowInPort := flow.GetInPort(flowItem)
691 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000692 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000693 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
694 continue
695 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
696 } else if flowInPort == dh.ponPortNumber {
697 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000698 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000699 "device-id": dh.deviceID, "inPort": flowInPort})
700 continue
701 } else {
702 // this is the relevant upstream flow
703 var loUniPort *onuUniPort
704 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
705 loUniPort = uniPort
706 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000707 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000708 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
709 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
710 flowInPort, dh.deviceID)
711 continue
712 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
713 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000714 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
715 // if not, we just throw some error here to have an indication about that, if we really need to support that
716 // then we would need to create some means to activate the internal stored flows
717 // after the device gets active automatically (and still with its dependency to the TechProfile)
718 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
719 // also abort for the other still possible flows here
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000720 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000721 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000722 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000723 return fmt.Errorf("improper device state on device %s", dh.deviceID)
724 }
725
mpagenko01e726e2020-10-23 09:45:29 +0000726 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000728 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
729 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000730 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000731 //try next flow after processing error
732 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000733 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000734 log.Fields{"device-id": dh.deviceID, "error": err})
735 retError = err
736 continue
737 //return err
738 } else { // if last setting succeeds, overwrite possibly previously set error
739 retError = nil
740 }
741 }
742 }
743 }
744 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000745}
746
Himani Chawla6d2ae152020-09-02 13:11:20 +0530747//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000748//following are the expected device states after this activity:
749//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
750// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000751func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
752 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000753
mpagenko900ee4b2020-10-12 11:56:34 +0000754 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000755 //note that disableDevice sequences in some 'ONU active' state may yield also
756 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000757 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000758 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000759 //disable-device shall be just a UNi/ONU-G related admin state setting
760 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000761
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000762 if dh.isReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000763 // disable UNI ports/ONU
764 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
765 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000766 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000767 } else { //LockStateFSM already init
768 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000769 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000770 }
771 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000772 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000773 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000774 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000775 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
776 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000777 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000778 }
mpagenko01e726e2020-10-23 09:45:29 +0000779 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000780
781 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000782 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000783 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300784 }
785}
786
Himani Chawla6d2ae152020-09-02 13:11:20 +0530787//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000788func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
789 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000790
mpagenkoaa3afe92021-05-21 16:20:58 +0000791 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000792 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
793 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
794 // for real ONU's that should have nearly no influence
795 // Note that for real ONU's there is anyway a problematic situation with following sequence:
796 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
797 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
798 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000799 dh.setReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000800
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000801 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000802 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000803 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000804 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000805 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000806 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000807 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000808 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300809}
810
dbainbri4d3a0dc2020-12-02 00:33:42 +0000811func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
812 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000813
dbainbri4d3a0dc2020-12-02 00:33:42 +0000814 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000815 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000816 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000817 return
818 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000819 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000820 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000821 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000822 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000823 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000824 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000825 dh.stopReconciling(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000826 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000827 }
Himani Chawla4d908332020-08-31 12:30:20 +0530828 var onuIndication oop.OnuIndication
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000829 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000830 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
831 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
832 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
833 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000834 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000835 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000836}
837
dbainbri4d3a0dc2020-12-02 00:33:42 +0000838func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
839 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000840
dbainbri4d3a0dc2020-12-02 00:33:42 +0000841 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000842 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000843 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000844 if !dh.isSkipOnuConfigReconciling() {
845 dh.stopReconciling(ctx)
846 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000847 return
848 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000849 dh.pOnuTP.lockTpProcMutex()
850 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000851 pDevEntry.mutexPersOnuConfig.RLock()
852 defer pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000853
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000854 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000855 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000856 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000857 if !dh.isSkipOnuConfigReconciling() {
858 dh.stopReconciling(ctx)
859 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000860 return
861 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000862 techProfsFound := false
863 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000864 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000865 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
866 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000867 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000868 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000869 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000870 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000871 techProfsFound = true
Girish Gowdra041dcb32020-11-16 16:54:30 -0800872 for tpID := range uniData.PersTpPathMap {
873 // deadline context to ensure completion of background routines waited for
874 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
875 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000876 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000877
Girish Gowdra041dcb32020-11-16 16:54:30 -0800878 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
879 var wg sync.WaitGroup
880 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000881 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
882 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800883 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000884 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800885 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000886 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000887 if len(uniData.PersFlowParams) != 0 {
888 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000889 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000890 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000891 if !techProfsFound {
892 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
893 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000894 if !dh.isSkipOnuConfigReconciling() {
895 dh.stopReconciling(ctx)
896 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000897 return
898 }
899 if dh.isSkipOnuConfigReconciling() {
900 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
901 }
902 if !flowsFound {
903 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
904 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000905 if !dh.isSkipOnuConfigReconciling() {
906 dh.stopReconciling(ctx)
907 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000908 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000909}
910
dbainbri4d3a0dc2020-12-02 00:33:42 +0000911func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
912 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000913
dbainbri4d3a0dc2020-12-02 00:33:42 +0000914 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000915 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000916 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000917 if !dh.isSkipOnuConfigReconciling() {
918 dh.stopReconciling(ctx)
919 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000920 return
921 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000922 pDevEntry.mutexPersOnuConfig.RLock()
923 defer pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000924
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000925 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000926 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000927 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000928 if !dh.isSkipOnuConfigReconciling() {
929 dh.stopReconciling(ctx)
930 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000931 return
932 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000933 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000934 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000935 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
936 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000937 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000938 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000939 continue
940 }
941 if len(uniData.PersTpPathMap) == 0 {
942 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
943 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000944 // It doesn't make sense to configure any flows if no TPs are available
945 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000946 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000947 var uniPort *onuUniPort
948 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000949 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000950 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000951 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
952 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000953 if !dh.isSkipOnuConfigReconciling() {
954 dh.stopReconciling(ctx)
955 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000956 return
957 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000958 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200959 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000960 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000961 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000962 for _, flowData := range uniData.PersFlowParams {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000963 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200964 // If this is the last flow for the device we need to announce it the waiting
965 // chReconcilingFlowsFinished channel
966 if flowsProcessed == len(uniData.PersFlowParams)-1 {
967 lastFlowToReconcile = true
968 }
mpagenko01e726e2020-10-23 09:45:29 +0000969 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenkof1fc3862021-02-16 10:09:52 +0000970 dh.lockVlanConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000971 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000972 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000973 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200974 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000975 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000976 }
mpagenkof1fc3862021-02-16 10:09:52 +0000977 dh.lockVlanConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000978 } else {
mpagenkof1fc3862021-02-16 10:09:52 +0000979 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000980 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000981 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200982 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000983 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000984 }
985 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000986 flowsProcessed++
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000987 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000988 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{"device-id": dh.deviceID, "flowsProcessed": flowsProcessed,
989 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
990 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200991 // this can't be used as global finished reconciling flag because
992 // assumes is getting called before the state machines for the last flow is completed,
993 // while this is not guaranteed.
994 //dh.setReconcilingFlows(false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000995 }
996 if !flowsFound {
997 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
998 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000999 if !dh.isSkipOnuConfigReconciling() {
1000 dh.stopReconciling(ctx)
1001 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001002 return
1003 }
1004 if dh.isSkipOnuConfigReconciling() {
1005 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001006 }
1007}
1008
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001009func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
1010 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001011 dh.stopReconciling(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001012}
1013
dbainbri4d3a0dc2020-12-02 00:33:42 +00001014func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
1015 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001016
dbainbri4d3a0dc2020-12-02 00:33:42 +00001017 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001018 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001019 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +00001020 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001021 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001022 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001023
1024 // deadline context to ensure completion of background routines waited for
1025 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
Himani Chawlad96df182020-09-28 11:12:02 +05301026 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001027 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001028
1029 pDevEntry.resetKvProcessingErrorIndication()
1030
1031 var wg sync.WaitGroup
1032 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001033 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1034 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001035
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001036 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001037 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001038}
1039
mpagenko15ff4a52021-03-02 10:09:20 +00001040//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1041// before this change here return like this was used:
1042// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1043//was and is called in background - error return does not make sense
1044func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1045 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1046 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001047 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001048 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001049 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001050 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301051 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001052 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001053 return
Himani Chawla4d908332020-08-31 12:30:20 +05301054 }
mpagenko01e726e2020-10-23 09:45:29 +00001055
1056 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001057 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001058
dbainbri4d3a0dc2020-12-02 00:33:42 +00001059 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001060 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001061 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001062 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001063 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001064 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001065 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001066 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001067 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001068 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001069 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001070 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001071 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1072 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1073 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1074 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001075}
1076
mpagenkoc8bba412021-01-15 15:38:44 +00001077//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +00001078func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1079 apDownloadManager *adapterDownloadManager) error {
1080 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001081 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001082
1083 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001084 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1085 if pDevEntry == nil {
1086 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1087 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1088 }
1089
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001090 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001091 var inactiveImageID uint16
1092 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1093 dh.lockUpgradeFsm.Lock()
1094 defer dh.lockUpgradeFsm.Unlock()
1095 if dh.pOnuUpradeFsm == nil {
1096 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1097 if err == nil {
1098 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1099 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1100 "device-id": dh.deviceID, "error": err})
1101 }
1102 } else {
1103 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001104 "device-id": dh.deviceID, "error": err})
1105 }
mpagenko15ff4a52021-03-02 10:09:20 +00001106 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1107 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1108 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1109 if pUpgradeStatemachine != nil {
1110 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1111 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1112 "device-id": dh.deviceID, "error": err})
1113 }
1114 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1115 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1116 // for now a second start of download should work again
1117 } else { //should never occur
1118 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1119 "device-id": dh.deviceID})
1120 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001121 }
mpagenko80622a52021-02-09 16:53:23 +00001122 }
mpagenko15ff4a52021-03-02 10:09:20 +00001123 } else {
1124 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1125 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001126 }
1127 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001128 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1129 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001130 }
1131 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001132}
1133
mpagenkoc26d4c02021-05-06 14:27:57 +00001134//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1135// after the OnuImage has been downloaded to the adapter, called in background
1136func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
1137 apDownloadManager *fileDownloadManager, aImageIdentifier string) {
1138
1139 var err error
1140 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1141 if pDevEntry == nil {
1142 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1143 return
1144 }
1145
1146 var inactiveImageID uint16
1147 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1148 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
1149 "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
1150 dh.lockUpgradeFsm.Lock()
1151 defer dh.lockUpgradeFsm.Unlock()
1152 if dh.pOnuUpradeFsm == nil {
1153 //OmciOnuSwUpgradeDone could be used to create some Kafka event with information on upgrade completion,
1154 // but none yet defined
1155 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1156 if err == nil {
1157 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
Holger Hildebrandtac010732021-06-02 13:35:39 +00001158 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00001159 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1160 "device-id": dh.deviceID, "error": err})
1161 return
1162 }
1163 } else {
1164 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1165 "device-id": dh.deviceID, "error": err})
1166 }
1167 return
1168 }
1169 //OnuSw upgrade already running - restart (with possible abort of running)
1170 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1171 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1172 if pUpgradeStatemachine != nil {
1173 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1174 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1175 "device-id": dh.deviceID, "error": err})
1176 return
1177 }
1178 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1179 // for now a second start of download should work again - must still be initiated by user
1180 } else { //should never occur
1181 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1182 "device-id": dh.deviceID})
1183 }
1184 return
1185 }
1186 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1187 "device-id": dh.deviceID, "error": err})
1188}
1189
1190//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001191func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1192 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001193 var err error
1194 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1195 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1196 // 2.) activation of the inactive image
1197
1198 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1199 if pDevEntry == nil {
1200 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001201 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001202 }
1203 dh.lockUpgradeFsm.RLock()
1204 if dh.pOnuUpradeFsm != nil {
1205 dh.lockUpgradeFsm.RUnlock()
1206 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1207 dh.deviceID, dh.deviceID)
1208 if getErr != nil || onuVolthaDevice == nil {
1209 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.deviceID, "err": getErr})
mpagenko183647c2021-06-08 15:25:04 +00001210 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001211 }
1212 // use the OnuVendor identification from this device for the internal unique name
1213 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1214 // 1.) check a started upgrade process and rely the activation request to it
1215 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001216 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001217 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1218 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001219 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001220 }
mpagenko183647c2021-06-08 15:25:04 +00001221 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1222 "device-id": dh.deviceID, "image-id": imageIdentifier})
1223 var pImageStates *voltha.ImageState
1224 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1225 pImageStates = &voltha.ImageState{}
1226 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1227 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1228 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1229 }
1230 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001231 } //else
1232 dh.lockUpgradeFsm.RUnlock()
1233
1234 // 2.) check if requested image-version equals the inactive one and start its activation
1235 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1236 var inactiveImageID uint16
1237 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1238 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1239 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
mpagenko183647c2021-06-08 15:25:04 +00001240 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001241 }
1242 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1243 if err == nil {
1244 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1245 inactiveImageID, aCommitRequest); err != nil {
1246 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1247 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001248 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001249 }
1250 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1251 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001252 var pImageStates *voltha.ImageState
1253 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1254 pImageStates := &voltha.ImageState{}
1255 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1256 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1257 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1258 }
1259 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001260 } //else
1261 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1262 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001263 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001264}
1265
1266//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001267func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1268 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001269 var err error
1270 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1271 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1272 // 2.) commitment of the active image
1273
1274 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1275 if pDevEntry == nil {
1276 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001277 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001278 }
1279 dh.lockUpgradeFsm.RLock()
1280 if dh.pOnuUpradeFsm != nil {
1281 dh.lockUpgradeFsm.RUnlock()
1282 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1283 dh.deviceID, dh.deviceID)
1284 if getErr != nil || onuVolthaDevice == nil {
1285 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.deviceID, "err": getErr})
mpagenko183647c2021-06-08 15:25:04 +00001286 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001287 }
1288 // use the OnuVendor identification from this device for the internal unique name
1289 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1290 // 1.) check a started upgrade process and rely the commitment request to it
1291 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001292 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001293 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1294 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001295 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001296 }
mpagenko183647c2021-06-08 15:25:04 +00001297 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1298 "device-id": dh.deviceID, "image-id": imageIdentifier})
1299 var pImageStates *voltha.ImageState
1300 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1301 pImageStates := &voltha.ImageState{}
1302 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1303 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1304 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1305 }
1306 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001307 } //else
1308 dh.lockUpgradeFsm.RUnlock()
1309
mpagenko183647c2021-06-08 15:25:04 +00001310 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001311 var activeImageID uint16
1312 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1313 logger.Errorw(ctx, "get active image failed", log.Fields{
1314 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
mpagenko183647c2021-06-08 15:25:04 +00001315 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001316 }
1317 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1318 if err == nil {
1319 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1320 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1321 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001322 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001323 }
1324 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1325 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001326 var pImageStates *voltha.ImageState
1327 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1328 pImageStates := &voltha.ImageState{}
1329 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1330 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1331 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1332 }
1333 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001334 } //else
1335 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1336 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001337 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001338}
1339
mpagenkoaa3afe92021-05-21 16:20:58 +00001340func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
1341 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1342 pDeviceImageState.DeviceId = dh.deviceID
mpagenko183647c2021-06-08 15:25:04 +00001343 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001344 dh.lockUpgradeFsm.RLock()
1345 if dh.pOnuUpradeFsm != nil {
1346 dh.lockUpgradeFsm.RUnlock()
mpagenko183647c2021-06-08 15:25:04 +00001347 if pImageStates, err := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion); err == nil {
mpagenkoaa3afe92021-05-21 16:20:58 +00001348 pDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
1349 pDeviceImageState.ImageState.Reason = pImageStates.Reason
1350 pDeviceImageState.ImageState.ImageState = pImageStates.ImageState
1351 } else {
1352 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1353 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1354 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1355 }
1356 } else {
1357 dh.lockUpgradeFsm.RUnlock()
1358 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1359 if dh.upgradeSuccess {
1360 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
1361 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMITTED
1362 } else {
1363 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1364 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1365 }
1366 }
1367}
1368
1369func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1370 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1371 pDeviceImageState.DeviceId = dh.deviceID
mpagenko7455fd42021-06-10 16:25:55 +00001372 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001373 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1374 dh.lockUpgradeFsm.RLock()
1375 if dh.pOnuUpradeFsm != nil {
1376 dh.lockUpgradeFsm.RUnlock()
1377 //option: it could be also checked if the upgrade FSM is running on the given imageIdentifier or version
1378 // by now just straightforward assume this to be true
1379 dh.pOnuUpradeFsm.CancelProcessing(ctx)
1380 //nolint:misspell
1381 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
1382 //nolint:misspell
1383 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1384 } else {
1385 dh.lockUpgradeFsm.RUnlock()
1386 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1387 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1388 }
1389}
1390
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001391func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1392
1393 var onuImageStatus *OnuImageStatus
1394
1395 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1396 if pDevEntry != nil {
1397 onuImageStatus = NewOnuImageStatus(pDevEntry)
1398 pDevEntry.mutexOnuImageStatus.Lock()
1399 pDevEntry.pOnuImageStatus = onuImageStatus
1400 pDevEntry.mutexOnuImageStatus.Unlock()
1401
1402 } else {
1403 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1404 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1405 }
1406 images, err := onuImageStatus.getOnuImageStatus(ctx)
1407 pDevEntry.mutexOnuImageStatus.Lock()
1408 pDevEntry.pOnuImageStatus = nil
1409 pDevEntry.mutexOnuImageStatus.Unlock()
1410 return images, err
1411}
1412
Himani Chawla6d2ae152020-09-02 13:11:20 +05301413// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001414// #####################################################################################
1415
1416// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301417// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001418
dbainbri4d3a0dc2020-12-02 00:33:42 +00001419func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1420 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event), "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001421}
1422
1423// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001424func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001425
dbainbri4d3a0dc2020-12-02 00:33:42 +00001426 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001427 var err error
1428
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001429 // populate what we know. rest comes later after mib sync
1430 dh.device.Root = false
1431 dh.device.Vendor = "OpenONU"
1432 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001433 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001434 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001435
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001436 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001437
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001438 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1440 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301441 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001442 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001443 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001444 log.Fields{"device-id": dh.deviceID})
1445 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001446
Himani Chawla4d908332020-08-31 12:30:20 +05301447 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001448 dh.ponPortNumber = dh.device.ParentPortNo
1449
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001450 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1451 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1452 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001453 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001454 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301455 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001456
1457 /*
1458 self._pon = PonPort.create(self, self._pon_port_number)
1459 self._pon.add_peer(self.parent_id, self._pon_port_number)
1460 self.logger.debug('adding-pon-port-to-agent',
1461 type=self._pon.get_port().type,
1462 admin_state=self._pon.get_port().admin_state,
1463 oper_status=self._pon.get_port().oper_status,
1464 )
1465 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001466 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001467 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001468 var ponPortNo uint32 = 1
1469 if dh.ponPortNumber != 0 {
1470 ponPortNo = dh.ponPortNumber
1471 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001472
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001473 pPonPort := &voltha.Port{
1474 PortNo: ponPortNo,
1475 Label: fmt.Sprintf("pon-%d", ponPortNo),
1476 Type: voltha.Port_PON_ONU,
1477 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301478 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001479 PortNo: ponPortNo}}, // Peer port is parent's port number
1480 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001481 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1482 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001483 e.Cancel(err)
1484 return
1485 }
1486 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001487 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001488 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001489 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001490}
1491
1492// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001493func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001494
dbainbri4d3a0dc2020-12-02 00:33:42 +00001495 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001496 var err error
1497 /*
1498 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1499 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1500 return nil
1501 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001502 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1503 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001504 e.Cancel(err)
1505 return
1506 }
1507
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001508 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001509 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001510 // reconcilement will be continued after mib download is done
1511 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001512
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001513 /*
1514 ############################################################################
1515 # Setup Alarm handler
1516 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1517 device.serial_number)
1518 ############################################################################
1519 # Setup PM configuration for this device
1520 # Pass in ONU specific options
1521 kwargs = {
1522 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1523 'heartbeat': self.heartbeat,
1524 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1525 }
1526 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1527 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1528 self.logical_device_id, device.serial_number,
1529 grouped=True, freq_override=False, **kwargs)
1530 pm_config = self._pm_metrics.make_proto()
1531 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1532 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1533 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1534
1535 # Note, ONU ID and UNI intf set in add_uni_port method
1536 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1537 ani_ports=[self._pon])
1538
1539 # Code to Run OMCI Test Action
1540 kwargs_omci_test_action = {
1541 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1542 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1543 }
1544 serial_number = device.serial_number
1545 self._test_request = OmciTestRequest(self.core_proxy,
1546 self.omci_agent, self.device_id,
1547 AniG, serial_number,
1548 self.logical_device_id,
1549 exclusive=False,
1550 **kwargs_omci_test_action)
1551
1552 self.enabled = True
1553 else:
1554 self.logger.info('onu-already-activated')
1555 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001556
dbainbri4d3a0dc2020-12-02 00:33:42 +00001557 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001558}
1559
1560// doStateConnected get the device info and update to voltha core
1561// for comparison of the original method (not that easy to uncomment): compare here:
1562// voltha-openolt-adapter/adaptercore/device_handler.go
1563// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001564func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001565
dbainbri4d3a0dc2020-12-02 00:33:42 +00001566 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301567 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001568 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001569 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001570}
1571
1572// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001573func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001574
dbainbri4d3a0dc2020-12-02 00:33:42 +00001575 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301576 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001577 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001578 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001579
1580 /*
1581 // Synchronous call to update device state - this method is run in its own go routine
1582 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1583 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001584 logger.Errorw("Failed to update device with OLT UP indication", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001585 return err
1586 }
1587 return nil
1588 */
1589}
1590
1591// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001592func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001593
dbainbri4d3a0dc2020-12-02 00:33:42 +00001594 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001595 var err error
1596
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001597 device := dh.device
1598 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001599 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001600 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001601 e.Cancel(err)
1602 return
1603 }
1604
1605 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001606 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001607 /*
1608 // Update the all ports state on that device to disable
1609 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001610 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001611 return er
1612 }
1613
1614 //Update the device oper state and connection status
1615 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1616 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1617 dh.device = cloned
1618
1619 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001620 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001621 return er
1622 }
1623
1624 //get the child device for the parent device
1625 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1626 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001627 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001628 return err
1629 }
1630 for _, onuDevice := range onuDevices.Items {
1631
1632 // Update onu state as down in onu adapter
1633 onuInd := oop.OnuIndication{}
1634 onuInd.OperState = "down"
1635 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1636 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1637 if er != nil {
1638 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001639 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001640 //Do not return here and continue to process other ONUs
1641 }
1642 }
1643 // * Discovered ONUs entries need to be cleared , since after OLT
1644 // is up, it starts sending discovery indications again* /
1645 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001646 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001647 return nil
1648 */
Himani Chawla4d908332020-08-31 12:30:20 +05301649 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001650 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001651 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001652}
1653
Himani Chawla6d2ae152020-09-02 13:11:20 +05301654// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001655// #################################################################################
1656
1657// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301658// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001659
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001660//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001661func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001662 dh.lockDevice.RLock()
1663 pOnuDeviceEntry := dh.pOnuOmciDevice
1664 if aWait && pOnuDeviceEntry == nil {
1665 //keep the read sema short to allow for subsequent write
1666 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001667 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001668 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1669 // so it might be needed to wait here for that event with some timeout
1670 select {
1671 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001672 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001673 return nil
1674 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001675 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001676 // if written now, we can return the written value without sema
1677 return dh.pOnuOmciDevice
1678 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001679 }
mpagenko3af1f032020-06-10 08:53:41 +00001680 dh.lockDevice.RUnlock()
1681 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001682}
1683
Himani Chawla6d2ae152020-09-02 13:11:20 +05301684//setOnuDeviceEntry sets the ONU device entry within the handler
1685func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001686 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001687 dh.lockDevice.Lock()
1688 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001689 dh.pOnuOmciDevice = apDeviceEntry
1690 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001691 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301692 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001693 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001694}
1695
Himani Chawla6d2ae152020-09-02 13:11:20 +05301696//addOnuDeviceEntry creates a new ONU device or returns the existing
1697func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001698 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001699
dbainbri4d3a0dc2020-12-02 00:33:42 +00001700 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001701 if deviceEntry == nil {
1702 /* costum_me_map in python code seems always to be None,
1703 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1704 /* also no 'clock' argument - usage open ...*/
1705 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001706 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001707 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001708 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301709 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001710 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001711 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001712 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001713 // fire deviceEntry ready event to spread to possibly waiting processing
1714 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001715 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001716 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001717 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001718 }
1719 // might be updated with some error handling !!!
1720 return nil
1721}
1722
dbainbri4d3a0dc2020-12-02 00:33:42 +00001723func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1724 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001725 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1726
1727 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001728
dbainbri4d3a0dc2020-12-02 00:33:42 +00001729 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001730 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001731 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001732 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1733 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001734 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001735 if err := dh.storePersistentData(ctx); err != nil {
1736 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001737 log.Fields{"device-id": dh.deviceID, "err": err})
1738 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001739 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001740 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001742 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1743 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001744 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001745 }
1746 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001747 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001748 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001749
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001750 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001751 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001752 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001753 logger.Debugw(ctx, "reconciling - uni-ports were not unlocked before adapter restart - resume with a normal start-up",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001754 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001755 dh.stopReconciling(ctx)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001756 } else {
1757 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001758 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001759 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001760 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1761 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1762 // in python code it looks as the started onu_omci_device might have been updated with some new instance state of the core device
mpagenkoaf801632020-07-03 10:00:42 +00001763 // but I would not know why, and the go code anyway does not work with the device directly anymore in the OnuDeviceEntry
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001764 // so let's just try to keep it simple ...
1765 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001766 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001767 if err != nil || device == nil {
1768 //TODO: needs to handle error scenarios
1769 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1770 return errors.New("Voltha Device not found")
1771 }
1772 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001773
dbainbri4d3a0dc2020-12-02 00:33:42 +00001774 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001775 return err
mpagenko3af1f032020-06-10 08:53:41 +00001776 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001777
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001778 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001779
1780 /* this might be a good time for Omci Verify message? */
1781 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001782 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001783 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001784 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001785 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001786
1787 /* give the handler some time here to wait for the OMCi verification result
1788 after Timeout start and try MibUpload FSM anyway
1789 (to prevent stopping on just not supported OMCI verification from ONU) */
1790 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001791 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001792 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001793 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001794 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001795 }
1796
1797 /* In py code it looks earlier (on activate ..)
1798 # Code to Run OMCI Test Action
1799 kwargs_omci_test_action = {
1800 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1801 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1802 }
1803 serial_number = device.serial_number
1804 self._test_request = OmciTestRequest(self.core_proxy,
1805 self.omci_agent, self.device_id,
1806 AniG, serial_number,
1807 self.logical_device_id,
1808 exclusive=False,
1809 **kwargs_omci_test_action)
1810 ...
1811 # Start test requests after a brief pause
1812 if not self._test_request_started:
1813 self._test_request_started = True
1814 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1815 reactor.callLater(tststart, self._test_request.start_collector)
1816
1817 */
1818 /* which is then: in omci_test_request.py : */
1819 /*
1820 def start_collector(self, callback=None):
1821 """
1822 Start the collection loop for an adapter if the frequency > 0
1823
1824 :param callback: (callable) Function to call to collect PM data
1825 """
1826 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1827 if callback is None:
1828 callback = self.perform_test_omci
1829
1830 if self.lc is None:
1831 self.lc = LoopingCall(callback)
1832
1833 if self.default_freq > 0:
1834 self.lc.start(interval=self.default_freq / 10)
1835
1836 def perform_test_omci(self):
1837 """
1838 Perform the initial test request
1839 """
1840 ani_g_entities = self._device.configuration.ani_g_entities
1841 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1842 is not None else None
1843 self._entity_id = ani_g_entities_ids[0]
1844 self.logger.info('perform-test', entity_class=self._entity_class,
1845 entity_id=self._entity_id)
1846 try:
1847 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1848 result = yield self._device.omci_cc.send(frame)
1849 if not result.fields['omci_message'].fields['success_code']:
1850 self.logger.info('Self-Test Submitted Successfully',
1851 code=result.fields[
1852 'omci_message'].fields['success_code'])
1853 else:
1854 raise TestFailure('Test Failure: {}'.format(
1855 result.fields['omci_message'].fields['success_code']))
1856 except TimeoutError as e:
1857 self.deferred.errback(failure.Failure(e))
1858
1859 except Exception as e:
1860 self.logger.exception('perform-test-Error', e=e,
1861 class_id=self._entity_class,
1862 entity_id=self._entity_id)
1863 self.deferred.errback(failure.Failure(e))
1864
1865 */
1866
1867 // PM related heartbeat??? !!!TODO....
1868 //self._heartbeat.enabled = True
1869
mpagenko1cc3cb42020-07-27 15:24:38 +00001870 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1871 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1872 * as further OltAdapter processing may rely on the deviceReason event 'MibUploadDone' as a result of the FSM processing
Himani Chawla4d908332020-08-31 12:30:20 +05301873 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001874 */
1875 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001876 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001877 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001878 if pMibUlFsm.Is(ulStDisabled) {
1879 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001880 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001881 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301882 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001883 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301884 //Determine ONU status and start/re-start MIB Synchronization tasks
1885 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001886 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301887 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001888 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001889 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001890 }
Himani Chawla4d908332020-08-31 12:30:20 +05301891 } else {
1892 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001893 logger.Errorw(ctx, "MibSyncFsm: Can't go to state examine_mds", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001894 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301895 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001896 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001897 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001898 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001899 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001900 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001901 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001902 }
1903 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001904 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001905 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001906 }
1907 return nil
1908}
1909
dbainbri4d3a0dc2020-12-02 00:33:42 +00001910func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001911 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001912 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001913 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001914 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001915
mpagenko900ee4b2020-10-12 11:56:34 +00001916 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1917 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1918 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001919 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001920 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001921 log.Fields{"device-id": dh.deviceID, "error": err})
1922 // abort: system behavior is just unstable ...
1923 return err
1924 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001925 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001926 _ = dh.deleteDevicePersistencyData(ctx) //ignore possible errors here and continue, hope is that data is synchronized with new ONU-Up
mpagenko900ee4b2020-10-12 11:56:34 +00001927
1928 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1929 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1930 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001931 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001932 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001933 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001934 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001935 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001936 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001937
1938 //TODO!!! remove existing traffic profiles
1939 /* from py code, if TP's exist, remove them - not yet implemented
1940 self._tp = dict()
1941 # Let TP download happen again
1942 for uni_id in self._tp_service_specific_task:
1943 self._tp_service_specific_task[uni_id].clear()
1944 for uni_id in self._tech_profile_download_done:
1945 self._tech_profile_download_done[uni_id].clear()
1946 */
1947
dbainbri4d3a0dc2020-12-02 00:33:42 +00001948 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001949
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001950 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00001951
dbainbri4d3a0dc2020-12-02 00:33:42 +00001952 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001953 // abort: system behavior is just unstable ...
1954 return err
1955 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001956 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001957 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001958 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001959 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001960 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001961 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001962 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001963 // abort: system behavior is just unstable ...
1964 return err
1965 }
1966 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001967 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001968 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001969 return nil
1970}
1971
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001972func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001973 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1974 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1975 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1976 // and using the stop/reset event should never harm
1977
dbainbri4d3a0dc2020-12-02 00:33:42 +00001978 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001979 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001980 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001981 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1982 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00001983 if pDevEntry.PDevOmciCC != nil {
1984 pDevEntry.PDevOmciCC.CancelRequestMonitoring()
1985 }
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001986 pDevEntry.mutexOnuImageStatus.RLock()
1987 if pDevEntry.pOnuImageStatus != nil {
1988 pDevEntry.pOnuImageStatus.CancelProcessing(ctx)
1989 }
1990 pDevEntry.mutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001991
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001992 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001993 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00001994 }
1995 //MibDownload may run
1996 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1997 if pMibDlFsm != nil {
1998 _ = pMibDlFsm.Event(dlEvReset)
1999 }
2000 //port lock/unlock FSM's may be active
2001 if dh.pUnlockStateFsm != nil {
2002 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2003 }
2004 if dh.pLockStateFsm != nil {
2005 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2006 }
2007 //techProfile related PonAniConfigFsm FSM may be active
2008 if dh.pOnuTP != nil {
2009 // should always be the case here
2010 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
2011 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08002012 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00002013 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002014 }
mpagenko900ee4b2020-10-12 11:56:34 +00002015 }
2016 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002017 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002018 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00002019 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
2020 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002021 dh.lockVlanConfig.RUnlock()
2022 //reset of all Fsm is always accompanied by global persistency data removal
2023 // no need to remove specific data
2024 pVlanFilterFsm.RequestClearPersistency(false)
2025 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002026 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002027 } else {
2028 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002029 }
2030 }
2031 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002032 if dh.getCollectorIsRunning() {
2033 // Stop collector routine
2034 dh.stopCollector <- true
2035 }
Himani Chawla1472c682021-03-17 17:11:14 +05302036 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302037 dh.stopAlarmManager <- true
2038 }
2039
mpagenko80622a52021-02-09 16:53:23 +00002040 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00002041 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002042 dh.lockUpgradeFsm.RLock()
2043 if dh.pOnuUpradeFsm != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00002044 dh.pOnuUpradeFsm.CancelProcessing(ctx)
mpagenko80622a52021-02-09 16:53:23 +00002045 }
2046 dh.lockUpgradeFsm.RUnlock()
2047
mpagenko7d6bb022021-03-11 15:07:55 +00002048 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002049 return nil
2050}
2051
dbainbri4d3a0dc2020-12-02 00:33:42 +00002052func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2053 logger.Debugw(ctx, "MibInSync event received, adding uni ports and locking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302054
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002055 // store persistent data collected during MIB upload processing
2056 if err := dh.storePersistentData(ctx); err != nil {
2057 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2058 log.Fields{"device-id": dh.deviceID, "err": err})
2059 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002060 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002061 dh.addAllUniPorts(ctx)
2062
mpagenkoa40e99a2020-11-17 13:50:39 +00002063 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2064 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2065 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2066 * disable/enable toggling here to allow traffic
2067 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2068 * like the py comment says:
2069 * # start by locking all the unis till mib sync and initial mib is downloaded
2070 * # this way we can capture the port down/up events when we are ready
2071 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302072
mpagenkoa40e99a2020-11-17 13:50:39 +00002073 // Init Uni Ports to Admin locked state
2074 // *** should generate UniLockStateDone event *****
2075 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002076 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002077 } else { //LockStateFSM already init
2078 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002079 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002080 }
2081}
2082
dbainbri4d3a0dc2020-12-02 00:33:42 +00002083func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2084 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302085 /* Mib download procedure -
2086 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2087 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002088 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002089 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002090 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002091 return
2092 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302093 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2094 if pMibDlFsm != nil {
2095 if pMibDlFsm.Is(dlStDisabled) {
2096 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002097 logger.Errorw(ctx, "MibDownloadFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302098 // maybe try a FSM reset and then again ... - TODO!!!
2099 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002100 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302101 // maybe use more specific states here for the specific download steps ...
2102 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002103 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302104 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002105 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302106 //Begin MIB data download (running autonomously)
2107 }
2108 }
2109 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002110 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002111 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302112 // maybe try a FSM reset and then again ... - TODO!!!
2113 }
2114 /***** Mib download started */
2115 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002116 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302117 }
2118}
2119
dbainbri4d3a0dc2020-12-02 00:33:42 +00002120func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2121 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302122 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002123 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002124 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002125 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002126 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2127 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2128 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2129 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002130 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302131 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
2132 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002133 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302134 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002135 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302136 }
2137 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002138 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302139 log.Fields{"device-id": dh.deviceID})
2140 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002141 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002142
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002143 if !dh.getCollectorIsRunning() {
2144 // Start PM collector routine
2145 go dh.startCollector(ctx)
2146 }
2147 if !dh.getAlarmManagerIsRunning(ctx) {
2148 go dh.startAlarmManager(ctx)
2149 }
2150
Girish Gowdrae0140f02021-02-02 16:55:09 -08002151 // Initialize classical L2 PM Interval Counters
2152 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2153 // There is no way we should be landing here, but if we do then
2154 // there is nothing much we can do about this other than log error
2155 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2156 }
2157
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002158 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002159
2160 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2161 if pDevEntry == nil {
2162 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2163 return
2164 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002165 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002166 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002167 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002168 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2169 log.Fields{"device-id": dh.deviceID})
2170 go dh.reconcileDeviceTechProf(ctx)
2171 // reconcilement will be continued after ani config is done
2172 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002173 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002174 // *** should generate UniUnlockStateDone event *****
2175 if dh.pUnlockStateFsm == nil {
2176 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2177 } else { //UnlockStateFSM already init
2178 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2179 dh.runUniLockFsm(ctx, false)
2180 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302181 }
2182}
2183
dbainbri4d3a0dc2020-12-02 00:33:42 +00002184func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2185 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302186
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002187 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002188 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002189 raisedTs := time.Now().Unix()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002190 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2191 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002192 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002193 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002194 return
2195 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002196 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002197 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002198 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002199 if err := dh.storePersistentData(ctx); err != nil {
2200 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002201 log.Fields{"device-id": dh.deviceID, "err": err})
2202 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302203 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002204 logger.Debugw(ctx, "reconciling - don't notify core that onu went to active but trigger tech profile config",
Himani Chawla26e555c2020-08-31 12:30:20 +05302205 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002206 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002207 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302208 }
2209}
2210
dbainbri4d3a0dc2020-12-02 00:33:42 +00002211func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2212 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002213 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002214 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00002215 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
2216 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002217 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002218 }
2219
dbainbri4d3a0dc2020-12-02 00:33:42 +00002220 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002221 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002222 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002223
2224 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002225 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002226
dbainbri4d3a0dc2020-12-02 00:33:42 +00002227 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002228 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002229 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002230 return
2231 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002232 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002233 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002234 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002235 if err := dh.storePersistentData(ctx); err != nil {
2236 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002237 log.Fields{"device-id": dh.deviceID, "err": err})
2238 }
mpagenko900ee4b2020-10-12 11:56:34 +00002239}
2240
dbainbri4d3a0dc2020-12-02 00:33:42 +00002241func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2242 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002243 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002244 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002245 voltha.OperStatus_ACTIVE); err != nil {
2246 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002247 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002248 }
2249
dbainbri4d3a0dc2020-12-02 00:33:42 +00002250 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002251 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002252 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002253 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002254
2255 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002256 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002257
dbainbri4d3a0dc2020-12-02 00:33:42 +00002258 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002259 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002260 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002261 return
2262 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002263 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002264 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002265 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002266 if err := dh.storePersistentData(ctx); err != nil {
2267 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002268 log.Fields{"device-id": dh.deviceID, "err": err})
2269 }
mpagenko900ee4b2020-10-12 11:56:34 +00002270}
2271
dbainbri4d3a0dc2020-12-02 00:33:42 +00002272func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002273 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002274 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002275 // attention: the device reason update is done based on ONU-UNI-Port related activity
2276 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002277 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002278 // which may be the case from some previous actvity even on this UNI Port (but also other UNI ports)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002279 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302280 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002281 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002282 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002283 }
2284 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002285 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002286 // attention: the device reason update is done based on ONU-UNI-Port related activity
2287 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002288 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002289 // which may be the case from some previous actvity even on this ONU port (but also other UNI ports)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002290 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002291 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002292 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302293}
2294
dbainbri4d3a0dc2020-12-02 00:33:42 +00002295func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2296 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002297 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302298 // attention: the device reason update is done based on ONU-UNI-Port related activity
2299 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302300
mpagenkof1fc3862021-02-16 10:09:52 +00002301 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002302 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002303 // which may be the case from some previous actvity on another UNI Port of the ONU
2304 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002305 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2306 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002307 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002308 }
2309 }
2310 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002311 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002312 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002313 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002314 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302315 }
mpagenkof1fc3862021-02-16 10:09:52 +00002316
2317 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2318 //events that request KvStore write
2319 if err := dh.storePersistentData(ctx); err != nil {
2320 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2321 log.Fields{"device-id": dh.deviceID, "err": err})
2322 }
2323 } else {
2324 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2325 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002326 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302327}
2328
Himani Chawla6d2ae152020-09-02 13:11:20 +05302329//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002330func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302331 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002332 case MibDatabaseSync:
2333 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002334 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002335 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002336 case UniLockStateDone:
2337 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002338 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002339 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002340 case MibDownloadDone:
2341 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002342 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002343 }
2344 case UniUnlockStateDone:
2345 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002346 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002347 }
mpagenko900ee4b2020-10-12 11:56:34 +00002348 case UniEnableStateDone:
2349 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002350 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002351 }
2352 case UniDisableStateDone:
2353 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002354 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002355 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002356 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002357 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002358 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002359 }
mpagenkof1fc3862021-02-16 10:09:52 +00002360 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002361 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002362 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002363 }
mpagenkoaa3afe92021-05-21 16:20:58 +00002364 case OmciOnuSwUpgradeDone:
2365 {
2366 dh.upgradeSuccess = true
2367 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002368 default:
2369 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002370 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002371 }
2372 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002373}
2374
dbainbri4d3a0dc2020-12-02 00:33:42 +00002375func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002376 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002377 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302378 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002379 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002380 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002381 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302382 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002383 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002384 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002385 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002386 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002387 //store UniPort with the System-PortNumber key
2388 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002389 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002390 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002391 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2392 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002393 } //error logging already within UniPort method
2394 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002395 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002396 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002397 }
2398 }
2399}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002400
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002401func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2402 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2403 if pDevEntry == nil {
2404 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2405 return
2406 }
2407 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2408 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2409 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2410 for _, mgmtEntityID := range pptpInstKeys {
2411 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2412 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2413 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2414 i++
2415 }
2416 } else {
2417 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2418 }
2419 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2420 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2421 for _, mgmtEntityID := range veipInstKeys {
2422 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2423 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2424 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2425 i++
2426 }
2427 } else {
2428 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2429 }
2430 if i == 0 {
2431 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2432 }
2433}
2434
mpagenko3af1f032020-06-10 08:53:41 +00002435// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002436func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002437 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302438 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002439 // with following remark:
2440 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2441 // # load on the core
2442
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002443 // lock_ports(false) as done in py code here is shifted to separate call from device event processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002444
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002445 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002446 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002447 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002448 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302449 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002450 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002451 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002452 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002453 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002454 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002455 }
mpagenko3af1f032020-06-10 08:53:41 +00002456 }
2457 }
2458}
2459
2460// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002461func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002462 // compare enableUniPortStateUpdate() above
2463 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2464 for uniNo, uniPort := range dh.uniEntityMap {
2465 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002466
2467 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002468 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302469 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002470 if !dh.isReconciling() {
2471 //maybe also use getter functions on uniPort - perhaps later ...
2472 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2473 } else {
2474 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2475 }
2476
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002477 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002478 }
2479}
2480
2481// ONU_Active/Inactive announcement on system KAFKA bus
2482// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002483func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002484 var de voltha.DeviceEvent
2485 eventContext := make(map[string]string)
2486 //Populating event context
2487 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002488 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002489 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002490 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302491 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002492 return //TODO with VOL-3045: rw-core is unresponsive: report error and/or perform self-initiated onu-reset?
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002493 }
2494 oltSerialNumber := parentDevice.SerialNumber
2495
2496 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2497 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2498 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302499 eventContext["olt-serial-number"] = oltSerialNumber
2500 eventContext["device-id"] = aDeviceID
2501 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002502 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
2503 if deviceEntry := dh.getOnuDeviceEntry(ctx, false); deviceEntry != nil {
2504 deviceEntry.mutexPersOnuConfig.RLock()
2505 eventContext["equipment-id"] = deviceEntry.sOnuPersistentData.PersEquipmentID
2506 deviceEntry.mutexPersOnuConfig.RUnlock()
2507 eventContext["software-version"] = deviceEntry.getActiveImageVersion(ctx)
2508 deviceEntry.mutexPersOnuConfig.RLock()
2509 eventContext["vendor"] = deviceEntry.sOnuPersistentData.PersVendorID
2510 deviceEntry.mutexPersOnuConfig.RUnlock()
2511 eventContext["inactive-software-version"] = deviceEntry.getInactiveImageVersion(ctx)
2512 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2513 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2514 } else {
2515 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2516 log.Fields{"device-id": aDeviceID})
2517 return
2518 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002519
2520 /* Populating device event body */
2521 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302522 de.ResourceId = aDeviceID
2523 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002524 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2525 de.Description = fmt.Sprintf("%s Event - %s - %s",
2526 cEventObjectType, cOnuActivatedEvent, "Raised")
2527 } else {
2528 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2529 de.Description = fmt.Sprintf("%s Event - %s - %s",
2530 cEventObjectType, cOnuActivatedEvent, "Cleared")
2531 }
2532 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002533 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2534 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302535 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002536 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002537 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302538 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002539}
2540
Himani Chawla4d908332020-08-31 12:30:20 +05302541// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002542func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002543 chLSFsm := make(chan Message, 2048)
2544 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302545 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002546 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002547 sFsmName = "LockStateFSM"
2548 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002549 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002550 sFsmName = "UnLockStateFSM"
2551 }
mpagenko3af1f032020-06-10 08:53:41 +00002552
dbainbri4d3a0dc2020-12-02 00:33:42 +00002553 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002554 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002555 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002556 return
2557 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002558 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002559 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002560 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302561 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002562 dh.pLockStateFsm = pLSFsm
2563 } else {
2564 dh.pUnlockStateFsm = pLSFsm
2565 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002566 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002567 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002568 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002569 }
2570}
2571
2572// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002573func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002574 /* Uni Port lock/unlock procedure -
2575 ***** should run via 'adminDone' state and generate the argument requested event *****
2576 */
2577 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302578 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002579 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2580 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2581 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002582 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302583 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002584 }
2585 } else {
2586 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2587 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2588 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002589 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302590 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002591 }
2592 }
2593 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002594 if pLSStatemachine.Is(uniStDisabled) {
2595 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002596 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002597 // maybe try a FSM reset and then again ... - TODO!!!
2598 } else {
2599 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002600 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002601 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002602 }
2603 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002604 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002605 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002606 // maybe try a FSM reset and then again ... - TODO!!!
2607 }
2608 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002609 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002610 // maybe try a FSM reset and then again ... - TODO!!!
2611 }
2612}
2613
mpagenko80622a52021-02-09 16:53:23 +00002614// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002615func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002616 //in here lockUpgradeFsm is already locked
2617 chUpgradeFsm := make(chan Message, 2048)
2618 var sFsmName = "OnuSwUpgradeFSM"
2619 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002620 if apDevEntry.PDevOmciCC == nil {
2621 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2622 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002623 }
mpagenko15ff4a52021-03-02 10:09:20 +00002624 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002625 sFsmName, chUpgradeFsm)
2626 if dh.pOnuUpradeFsm != nil {
2627 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2628 if pUpgradeStatemachine != nil {
2629 if pUpgradeStatemachine.Is(upgradeStDisabled) {
mpagenkoaa3afe92021-05-21 16:20:58 +00002630 dh.upgradeSuccess = false //for start of upgrade processing reset the last indication
mpagenko80622a52021-02-09 16:53:23 +00002631 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2632 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2633 // maybe try a FSM reset and then again ... - TODO!!!
2634 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2635 }
2636 /***** LockStateFSM started */
2637 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2638 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2639 } else {
2640 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2641 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2642 // maybe try a FSM reset and then again ... - TODO!!!
2643 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2644 }
2645 } else {
2646 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2647 // maybe try a FSM reset and then again ... - TODO!!!
2648 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2649 }
2650 } else {
2651 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2652 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2653 }
2654 return nil
2655}
2656
2657// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2658func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2659 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2660 "device-id": dh.deviceID})
2661 dh.lockUpgradeFsm.Lock()
2662 defer dh.lockUpgradeFsm.Unlock()
2663 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2664}
2665
mpagenko15ff4a52021-03-02 10:09:20 +00002666// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2667func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2668 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2669 if pDevEntry == nil {
2670 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2671 return
2672 }
2673
2674 dh.lockUpgradeFsm.RLock()
2675 defer dh.lockUpgradeFsm.RUnlock()
2676 if dh.pOnuUpradeFsm != nil {
2677 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2678 if pUpgradeStatemachine != nil {
2679 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2680 // (some manual forced commit could do without)
2681 if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
mpagenko183647c2021-06-08 15:25:04 +00002682 // here no need to update the upgrade image state to activated as the state will be immediately be set to committing
mpagenko59498c12021-03-18 14:15:15 +00002683 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko15ff4a52021-03-02 10:09:20 +00002684 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2685 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2686 return
2687 }
2688 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2689 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2690 } else {
2691 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2692 log.Fields{"device-id": dh.deviceID})
2693 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2694 return
2695 }
mpagenko183647c2021-06-08 15:25:04 +00002696 } else {
2697 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2698 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2699 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2700 if dh.pOnuUpradeFsm.inactiveImageMeID == activeImageID {
2701 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2702 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2703 dh.pOnuUpradeFsm.SetImageState(ctx, voltha.ImageState_IMAGE_ACTIVE)
2704 }
2705 }
mpagenko15ff4a52021-03-02 10:09:20 +00002706 }
2707 }
2708 } else {
2709 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2710 }
2711}
2712
Himani Chawla6d2ae152020-09-02 13:11:20 +05302713//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002714func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002715
2716 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002717 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002718 kvbackend := &db.Backend{
2719 Client: dh.pOpenOnuAc.kvClient,
2720 StoreType: dh.pOpenOnuAc.KVStoreType,
2721 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002722 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002723 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2724 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002725
mpagenkoaf801632020-07-03 10:00:42 +00002726 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002727}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002728func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302729 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002730
mpagenkodff5dda2020-08-28 11:52:01 +00002731 for _, field := range flow.GetOfbFields(apFlowItem) {
2732 switch field.Type {
2733 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2734 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002735 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002736 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2737 }
mpagenko01e726e2020-10-23 09:45:29 +00002738 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002739 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2740 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302741 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002742 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302743 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2744 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002745 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2746 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002747 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2748 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302749 return
mpagenkodff5dda2020-08-28 11:52:01 +00002750 }
2751 }
mpagenko01e726e2020-10-23 09:45:29 +00002752 */
mpagenkodff5dda2020-08-28 11:52:01 +00002753 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2754 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302755 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002756 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302757 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002758 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302759 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002760 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002761 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302762 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002763 }
2764 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2765 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302766 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002767 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002768 "PCP": loAddPcp})
2769 }
2770 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2771 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002772 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002773 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2774 }
2775 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2776 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002777 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002778 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2779 }
2780 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2781 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002782 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002783 "IPv4-DST": field.GetIpv4Dst()})
2784 }
2785 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2786 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002787 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002788 "IPv4-SRC": field.GetIpv4Src()})
2789 }
2790 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2791 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002792 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002793 "Metadata": field.GetTableMetadata()})
2794 }
2795 /*
2796 default:
2797 {
2798 //all other entires ignored
2799 }
2800 */
2801 }
2802 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302803}
mpagenkodff5dda2020-08-28 11:52:01 +00002804
dbainbri4d3a0dc2020-12-02 00:33:42 +00002805func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002806 for _, action := range flow.GetActions(apFlowItem) {
2807 switch action.Type {
2808 /* not used:
2809 case of.OfpActionType_OFPAT_OUTPUT:
2810 {
mpagenko01e726e2020-10-23 09:45:29 +00002811 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002812 "Output": action.GetOutput()})
2813 }
2814 */
2815 case of.OfpActionType_OFPAT_PUSH_VLAN:
2816 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002817 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002818 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2819 }
2820 case of.OfpActionType_OFPAT_SET_FIELD:
2821 {
2822 pActionSetField := action.GetSetField()
2823 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002824 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002825 "OxcmClass": pActionSetField.Field.OxmClass})
2826 }
2827 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302828 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002829 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302830 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002831 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302832 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002833 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302834 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002835 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002836 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002837 "Type": pActionSetField.Field.GetOfbField().Type})
2838 }
2839 }
2840 /*
2841 default:
2842 {
2843 //all other entires ignored
2844 }
2845 */
2846 }
2847 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302848}
2849
2850//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002851func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302852 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2853 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2854 var loAddPcp, loSetPcp uint8
2855 var loIPProto uint32
2856 /* the TechProfileId is part of the flow Metadata - compare also comment within
2857 * OLT-Adapter:openolt_flowmgr.go
2858 * Metadata 8 bytes:
2859 * Most Significant 2 Bytes = Inner VLAN
2860 * Next 2 Bytes = Tech Profile ID(TPID)
2861 * Least Significant 4 Bytes = Port ID
2862 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2863 * subscriber related flows.
2864 */
2865
dbainbri4d3a0dc2020-12-02 00:33:42 +00002866 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302867 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002868 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302869 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002870 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302871 }
mpagenko551a4d42020-12-08 18:09:20 +00002872 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002873 loCookie := apFlowItem.GetCookie()
2874 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002875 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002876 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302877
dbainbri4d3a0dc2020-12-02 00:33:42 +00002878 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002879 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302880 if loIPProto == 2 {
2881 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2882 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002883 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2884 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302885 return nil
2886 }
mpagenko01e726e2020-10-23 09:45:29 +00002887 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002888 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002889
2890 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002891 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002892 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2893 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2894 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2895 //TODO!!: Use DeviceId within the error response to rwCore
2896 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002897 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002898 }
2899 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002900 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002901 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2902 } else {
2903 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2904 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2905 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302906 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002907 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002908 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002909 }
mpagenko9a304ea2020-12-16 15:54:01 +00002910
2911 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002912 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002913 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302914 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002915 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002916 loMatchVlan, loSetVlan, loSetPcp, false)
mpagenkof1fc3862021-02-16 10:09:52 +00002917 dh.lockVlanConfig.RUnlock()
2918 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002919 }
mpagenkof1fc3862021-02-16 10:09:52 +00002920 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002921 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002922 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false)
mpagenko01e726e2020-10-23 09:45:29 +00002923}
2924
2925//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002926func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002927 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2928 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2929 //no extra check is done on the rule parameters
2930 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2931 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2932 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2933 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002934 // - some possible 'delete-all' sequence would have to be implemented separately (where the cookies are don't care anyway)
mpagenko01e726e2020-10-23 09:45:29 +00002935 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002936 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002937
2938 /* TT related temporary workaround - should not be needed anymore
2939 for _, field := range flow.GetOfbFields(apFlowItem) {
2940 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2941 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002942 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002943 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2944 if loIPProto == 2 {
2945 // some workaround for TT workflow on proto == 2 (IGMP trap) -> the flow was not added, no need to remove
mpagenko551a4d42020-12-08 18:09:20 +00002946 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002947 log.Fields{"device-id": dh.deviceID})
2948 return nil
2949 }
2950 }
2951 } //for all OfbFields
2952 */
2953
mpagenko9a304ea2020-12-16 15:54:01 +00002954 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002955 dh.lockVlanConfig.RLock()
2956 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002957 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002958 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002959 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002960 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002961 log.Fields{"device-id": dh.deviceID})
2962 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002963 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002964 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002965
mpagenko01e726e2020-10-23 09:45:29 +00002966 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002967}
2968
Himani Chawla26e555c2020-08-31 12:30:20 +05302969// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002970// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002971func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002972 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002973 chVlanFilterFsm := make(chan Message, 2048)
2974
dbainbri4d3a0dc2020-12-02 00:33:42 +00002975 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002976 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002977 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302978 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002979 }
2980
dbainbri4d3a0dc2020-12-02 00:33:42 +00002981 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002982 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002983 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile)
mpagenkodff5dda2020-08-28 11:52:01 +00002984 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002985 dh.lockVlanConfig.Lock()
mpagenko7d6bb022021-03-11 15:07:55 +00002986 //ensure the mutex is locked throughout the state transition to 'starting' to prevent unintended (ignored) events to be sent there
2987 // (from parallel processing)
2988 defer dh.lockVlanConfig.Unlock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302989 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002990 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2991 if pVlanFilterStatemachine != nil {
2992 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2993 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002994 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302995 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002996 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302997 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002998 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302999 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3000 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003001 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003002 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003003 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303004 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003005 }
3006 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003007 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003008 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303009 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003010 }
3011 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003012 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003013 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05303014 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003015 }
3016 return nil
3017}
3018
mpagenkofc4f56e2020-11-04 17:17:49 +00003019//VerifyVlanConfigRequest checks on existence of a given uniPort
3020// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003021func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003022 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
3023 var pCurrentUniPort *onuUniPort
3024 for _, uniPort := range dh.uniEntityMap {
3025 // only if this port is validated for operState transfer
3026 if uniPort.uniID == uint8(aUniID) {
3027 pCurrentUniPort = uniPort
3028 break //found - end search loop
3029 }
3030 }
3031 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003032 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00003033 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
3034 return
3035 }
mpagenko551a4d42020-12-08 18:09:20 +00003036 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003037}
3038
mpagenkodff5dda2020-08-28 11:52:01 +00003039//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00003040func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003041 //TODO!! verify and start pending flow configuration
3042 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3043 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003044
3045 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303046 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003047 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003048 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
3049 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3050 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003051 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
3052 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
3053 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
3054 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
3055 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3056 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3057 } else {
3058 /***** UniVlanConfigFsm continued */
3059 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
3060 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3061 "UniPort": apUniPort.portNo})
3062 }
3063 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
3064 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
3065 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3066 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3067 } else {
3068 /***** UniVlanConfigFsm continued */
3069 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3070 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3071 "UniPort": apUniPort.portNo})
3072 }
mpagenkodff5dda2020-08-28 11:52:01 +00003073 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003074 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3075 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003076 "UniPort": apUniPort.portNo})
3077 }
3078 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003079 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3080 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3081 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003082 }
3083 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003084 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003085 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003086 }
mpagenkof1fc3862021-02-16 10:09:52 +00003087 } else {
3088 dh.lockVlanConfig.RUnlock()
3089 }
mpagenkodff5dda2020-08-28 11:52:01 +00003090}
3091
3092//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3093// intention is to provide this method to be called from VlanConfigFsm itself, when resources (and methods!) are cleaned up
dbainbri4d3a0dc2020-12-02 00:33:42 +00003094func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3095 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003096 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3097 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003098 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303099 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003100 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003101}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003102
mpagenkof1fc3862021-02-16 10:09:52 +00003103//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3104func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3105 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3106 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3107 // obviously then parallel processing on the cancel must be avoided
3108 // deadline context to ensure completion of background routines waited for
3109 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3110 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3111 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3112
3113 aPDevEntry.resetKvProcessingErrorIndication()
3114 var wg sync.WaitGroup
3115 wg.Add(1) // for the 1 go routine to finish
3116
3117 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3118 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3119
3120 return aPDevEntry.getKvProcessingErrorIndication()
3121}
3122
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003123//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3124//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003125func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3126 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003127
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003128 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003129 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003130 return nil
3131 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003132 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003133
dbainbri4d3a0dc2020-12-02 00:33:42 +00003134 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003135 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003136 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003137 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3138 }
3139 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3140
mpagenkof1fc3862021-02-16 10:09:52 +00003141 if aWriteToKvStore {
3142 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3143 }
3144 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003145}
3146
dbainbri4d3a0dc2020-12-02 00:33:42 +00003147func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003148 defer cancel() //ensure termination of context (may be pro forma)
3149 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003150 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003151 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003152}
3153
dbainbri4d3a0dc2020-12-02 00:33:42 +00003154func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003155
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003156 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003157 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003158 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003159 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3160 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003161 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003162 return err
3163 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003164 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003165 return nil
3166 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003167 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003168 return nil
3169}
3170
dbainbri4d3a0dc2020-12-02 00:33:42 +00003171func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3172 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003173 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003174 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003175 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3176 }
mpagenkof1fc3862021-02-16 10:09:52 +00003177 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003178}
3179
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003180func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
3181 var errStr string = ""
3182 for _, err := range errS {
3183 if err != nil {
3184 errStr = errStr + err.Error() + " "
3185 }
3186 }
3187 if errStr != "" {
3188 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
3189 }
3190 return nil
3191}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003192
3193// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003194// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003195func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3196 dh.lockDevice.RLock()
3197 defer dh.lockDevice.RUnlock()
3198 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3199 return uniPort.entityID, nil
3200 }
3201 return 0, errors.New("error-fetching-uni-port")
3202}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003203
3204// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003205func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3206 var errorsList []error
3207 logger.Infow(ctx, "update-pm-config", log.Fields{"device-id": dh.device.Id, "new-pm-configs": pmConfigs, "old-pm-config": dh.pmConfigs})
Girish Gowdrae09a6202021-01-12 18:10:59 -08003208
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003209 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3210 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3211 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3212
3213 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3214 // successfully.
3215 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3216 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3217 if len(errorsList) > 0 {
3218 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3219 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003220 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003221 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3222 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003223}
3224
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003225func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3226 var err error
3227 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003228 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003229
3230 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3231 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3232 errorsList = append(errorsList, err)
3233 }
3234 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003235 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003236
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003237 return errorsList
3238}
3239
3240func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3241 var err error
3242 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003243 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003244 // Check if group metric related config is updated
3245 for _, v := range pmConfigs.Groups {
3246 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3247 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3248 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3249
3250 if ok && m.frequency != v.GroupFreq {
3251 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3252 errorsList = append(errorsList, err)
3253 }
3254 }
3255 if ok && m.enabled != v.Enabled {
3256 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3257 errorsList = append(errorsList, err)
3258 }
3259 }
3260 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003261 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003262 return errorsList
3263}
3264
3265func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3266 var err error
3267 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003268 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003269 // Check if standalone metric related config is updated
3270 for _, v := range pmConfigs.Metrics {
3271 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003272 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003273 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3274
3275 if ok && m.frequency != v.SampleFreq {
3276 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3277 errorsList = append(errorsList, err)
3278 }
3279 }
3280 if ok && m.enabled != v.Enabled {
3281 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3282 errorsList = append(errorsList, err)
3283 }
3284 }
3285 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003286 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003287 return errorsList
3288}
3289
3290// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003291func (dh *deviceHandler) startCollector(ctx context.Context) {
3292 logger.Debugf(ctx, "startingCollector")
3293
3294 // Start routine to process OMCI GET Responses
3295 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003296 // Initialize the next metric collection time.
3297 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3298 // reset like onu rebooted.
3299 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003300 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003301 for {
3302 select {
3303 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003304 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003305 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003306 // Stop the L2 PM FSM
3307 go func() {
3308 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3309 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3310 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3311 }
3312 } else {
3313 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3314 }
3315 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003316 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3317 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3318 }
3319 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3320 dh.pOnuMetricsMgr.stopTicks <- true
3321 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003322
Girish Gowdrae09a6202021-01-12 18:10:59 -08003323 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003324 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3325 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3326 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3327 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3328 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003329 // Update the next metric collection time.
3330 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003331 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003332 } else {
3333 if dh.pmConfigs.Grouped { // metrics are managed as a group
3334 // parse through the group and standalone metrics to see it is time to collect their metrics
3335 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003336
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003337 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3338 // If the group is enabled AND (current time is equal to OR after nextCollectionInterval, collect the group metric)
Girish Gowdrae0140f02021-02-02 16:55:09 -08003339 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3340 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003341 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3342 }
3343 }
3344 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3345 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3346 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3347 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3348 }
3349 }
3350 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3351
3352 // parse through the group and update the next metric collection time
3353 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3354 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3355 // If group enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
Girish Gowdrae0140f02021-02-02 16:55:09 -08003356 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3357 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003358 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3359 }
3360 }
3361 // parse through the standalone metrics and update the next metric collection time
3362 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3363 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3364 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3365 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3366 }
3367 }
3368 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3369 } /* else { // metrics are not managed as a group
3370 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3371 } */
3372 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003373 }
3374 }
3375}
kesavandfdf77632021-01-26 23:40:33 -05003376
3377func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3378
3379 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3380 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3381}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003382
mpagenkof1fc3862021-02-16 10:09:52 +00003383func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3384 if pFsm == nil {
3385 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003386 }
mpagenkof1fc3862021-02-16 10:09:52 +00003387 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003388}
3389
mpagenkof1fc3862021-02-16 10:09:52 +00003390func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3391 var pFsm *fsm.FSM
3392 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3393 switch omciFsm {
3394 case cUploadFsm:
3395 {
3396 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3397 }
3398 case cDownloadFsm:
3399 {
3400 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3401 }
3402 case cUniLockFsm:
3403 {
3404 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3405 }
3406 case cUniUnLockFsm:
3407 {
3408 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3409 }
3410 case cL2PmFsm:
3411 {
3412 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3413 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3414 } else {
3415 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003416 }
3417 }
mpagenko80622a52021-02-09 16:53:23 +00003418 case cOnuUpgradeFsm:
3419 {
3420 dh.lockUpgradeFsm.RLock()
3421 defer dh.lockUpgradeFsm.RUnlock()
3422 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3423 }
mpagenkof1fc3862021-02-16 10:09:52 +00003424 default:
3425 {
3426 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3427 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3428 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003429 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003430 }
mpagenkof1fc3862021-02-16 10:09:52 +00003431 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003432}
3433
mpagenkof1fc3862021-02-16 10:09:52 +00003434func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3435 for _, v := range dh.pOnuTP.pAniConfigFsm {
3436 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003437 return false
3438 }
3439 }
3440 return true
3441}
3442
mpagenkof1fc3862021-02-16 10:09:52 +00003443func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3444 dh.lockVlanConfig.RLock()
3445 defer dh.lockVlanConfig.RUnlock()
3446 for _, v := range dh.UniVlanConfigFsmMap {
3447 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3448 return false
3449 }
3450 }
3451 return true //FSM not active - so there is no activity on omci
3452}
3453
3454func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3455 dh.lockVlanConfig.RLock()
3456 defer dh.lockVlanConfig.RUnlock()
3457 for _, v := range dh.UniVlanConfigFsmMap {
3458 if v.pAdaptFsm.pFsm != nil {
3459 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3460 return true //there is at least one VLAN FSM with some active configuration
3461 }
3462 }
3463 }
3464 return false //there is no VLAN FSM with some active configuration
3465}
3466
3467func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3468 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3469 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3470 return false
3471 }
3472 }
3473 // a further check is done to identify, if at least some data traffic related configuration exists
3474 // so that a user of this ONU could be 'online' (otherwise it makes no sense to check the MDS [with the intention to keep the user service up])
3475 return dh.checkUserServiceExists(ctx)
3476}
3477
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003478func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3479 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3480 if err := dh.resetFsms(ctx, false); err != nil {
3481 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3482 // TODO: fatal error reset ONU, delete deviceHandler!
3483 return
3484 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003485 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003486 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003487}
3488
3489func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3490 dh.mutexCollectorFlag.Lock()
3491 dh.collectorIsRunning = flagValue
3492 dh.mutexCollectorFlag.Unlock()
3493}
3494
3495func (dh *deviceHandler) getCollectorIsRunning() bool {
3496 dh.mutexCollectorFlag.RLock()
3497 flagValue := dh.collectorIsRunning
3498 dh.mutexCollectorFlag.RUnlock()
3499 return flagValue
3500}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303501
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303502func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3503 dh.mutextAlarmManagerFlag.Lock()
3504 dh.alarmManagerIsRunning = flagValue
3505 dh.mutextAlarmManagerFlag.Unlock()
3506}
3507
Himani Chawla1472c682021-03-17 17:11:14 +05303508func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303509 dh.mutextAlarmManagerFlag.RLock()
3510 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303511 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303512 dh.mutextAlarmManagerFlag.RUnlock()
3513 return flagValue
3514}
3515
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303516func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3517 logger.Debugf(ctx, "startingAlarmManager")
3518
3519 // Start routine to process OMCI GET Responses
3520 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303521 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303522 if stop := <-dh.stopAlarmManager; stop {
3523 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303524 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303525 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303526 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3527 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3528 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303529 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303530 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303531 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3532 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303533 }
3534}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003535
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003536func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003537 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003538
Maninder7961d722021-06-16 22:10:28 +05303539 connectStatus := voltha.ConnectStatus_UNREACHABLE
3540 operState := voltha.OperStatus_UNKNOWN
3541
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003542 if !dh.isReconciling() {
3543 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003544 logger.Debugw(ctx, "wait for channel signal or timeout",
3545 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003546 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003547 case success := <-dh.chReconcilingFinished:
3548 if success {
Maninderb5187552021-03-23 22:23:42 +05303549 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3550 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3551 log.Fields{"device-id": dh.deviceID})
3552 } else {
Maninderb5187552021-03-23 22:23:42 +05303553 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3554 connectStatus = voltha.ConnectStatus_REACHABLE
3555 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3556 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3557 operState = voltha.OperStatus_ACTIVE
3558 } else {
3559 operState = voltha.OperStatus_ACTIVATING
3560 }
3561 }
3562 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3563 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3564 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3565 operState = voltha.OperStatus_DISCOVERED
3566 }
3567
3568 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303569 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003570 logger.Debugw(ctx, "reconciling has been finished in time",
3571 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303572 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, operState); err != nil {
3573 logger.Errorw(ctx, "unable to update device state to core",
3574 log.Fields{"device-id": dh.deviceID, "Err": err})
3575 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003576 } else {
Maninderb5187552021-03-23 22:23:42 +05303577 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003578 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303579
3580 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3581 logger.Errorw(ctx, "No valid OnuDevice",
3582 log.Fields{"device-id": dh.deviceID})
3583 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3584 connectStatus = voltha.ConnectStatus_REACHABLE
3585 }
3586
3587 dh.deviceReconcileFailedUpdate(ctx, drReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003588 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003589 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003590 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3591 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303592
3593 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3594 logger.Errorw(ctx, "No valid OnuDevice",
3595 log.Fields{"device-id": dh.deviceID})
3596 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3597 connectStatus = voltha.ConnectStatus_REACHABLE
3598 }
3599
3600 dh.deviceReconcileFailedUpdate(ctx, drReconcileMaxTimeout, connectStatus)
3601
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003602 }
3603 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003604 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003605 dh.mutexReconcilingFlag.Unlock()
3606 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003607 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003608 dh.mutexReconcilingFlag.Lock()
3609 if skipOnuConfig {
3610 dh.reconciling = cSkipOnuConfigReconciling
3611 } else {
3612 dh.reconciling = cOnuConfigReconciling
3613 }
3614 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003615}
3616
3617func (dh *deviceHandler) stopReconciling(ctx context.Context) {
3618 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID})
3619 if dh.isReconciling() {
3620 dh.chReconcilingFinished <- true
3621 } else {
3622 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3623 }
3624}
3625
3626func (dh *deviceHandler) isReconciling() bool {
3627 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003628 defer dh.mutexReconcilingFlag.RUnlock()
3629 return dh.reconciling != cNoReconciling
3630}
3631
3632func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3633 dh.mutexReconcilingFlag.RLock()
3634 defer dh.mutexReconcilingFlag.RUnlock()
3635 return dh.reconciling == cSkipOnuConfigReconciling
3636}
3637
3638func (dh *deviceHandler) setDeviceReason(value uint8) {
3639 dh.mutexDeviceReason.Lock()
3640 dh.deviceReason = value
3641 dh.mutexDeviceReason.Unlock()
3642}
3643
3644func (dh *deviceHandler) getDeviceReason() uint8 {
3645 dh.mutexDeviceReason.RLock()
3646 value := dh.deviceReason
3647 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003648 return value
3649}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003650
3651func (dh *deviceHandler) getDeviceReasonString() string {
3652 return deviceReasonMap[dh.getDeviceReason()]
3653}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003654
3655func (dh *deviceHandler) setReconcilingFlows(value bool) {
3656 dh.mutexReconcilingFlowsFlag.Lock()
3657 dh.reconcilingFlows = value
3658 dh.mutexReconcilingFlowsFlag.Unlock()
3659}
3660
3661func (dh *deviceHandler) isReconcilingFlows() bool {
3662 dh.mutexReconcilingFlowsFlag.RLock()
3663 value := dh.reconcilingFlows
3664 dh.mutexReconcilingFlowsFlag.RUnlock()
3665 return value
3666}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003667
3668func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3669 dh.mutexReadyForOmciConfig.Lock()
3670 dh.readyForOmciConfig = flagValue
3671 dh.mutexReadyForOmciConfig.Unlock()
3672}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003673func (dh *deviceHandler) isReadyForOmciConfig() bool {
3674 dh.mutexReadyForOmciConfig.RLock()
3675 flagValue := dh.readyForOmciConfig
3676 dh.mutexReadyForOmciConfig.RUnlock()
3677 return flagValue
3678}
Maninder7961d722021-06-16 22:10:28 +05303679
3680func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
3681 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
3682 logger.Errorw(ctx, "unable to update device reason to core",
3683 log.Fields{"device-id": dh.deviceID, "Err": err})
3684 }
3685
3686 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
3687 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, voltha.OperStatus_RECONCILING_FAILED); err != nil {
3688 logger.Errorw(ctx, "unable to update device state to core",
3689 log.Fields{"device-id": dh.deviceID, "Err": err})
3690 }
3691}