blob: 49ee4aeb054178dc4dba653740403b7df6b024c1 [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
mpagenko1f8e8822021-06-25 14:10:21 +000028 "github.com/opencord/voltha-protos/v4/go/tech_profile"
29
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000030 "github.com/gogo/protobuf/proto"
31 "github.com/golang/protobuf/ptypes"
32 "github.com/looplab/fsm"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000033 me "github.com/opencord/omci-lib-go/generated"
Girish Gowdra50e56422021-06-01 16:46:04 -070034 "github.com/opencord/voltha-lib-go/v5/pkg/adapters/adapterif"
35 "github.com/opencord/voltha-lib-go/v5/pkg/db"
36 "github.com/opencord/voltha-lib-go/v5/pkg/events/eventif"
37 flow "github.com/opencord/voltha-lib-go/v5/pkg/flows"
38 "github.com/opencord/voltha-lib-go/v5/pkg/log"
dbainbri4d3a0dc2020-12-02 00:33:42 +000039 vc "github.com/opencord/voltha-protos/v4/go/common"
kesavandfdf77632021-01-26 23:40:33 -050040 "github.com/opencord/voltha-protos/v4/go/extension"
dbainbri4d3a0dc2020-12-02 00:33:42 +000041 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
42 "github.com/opencord/voltha-protos/v4/go/openflow_13"
43 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
44 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
45 oop "github.com/opencord/voltha-protos/v4/go/openolt"
46 "github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000047)
48
49/*
50// Constants for number of retries and for timeout
51const (
52 MaxRetry = 10
53 MaxTimeOutInMs = 500
54)
55*/
56
mpagenko1cc3cb42020-07-27 15:24:38 +000057const (
58 // events of Device FSM
59 devEvDeviceInit = "devEvDeviceInit"
60 devEvGrpcConnected = "devEvGrpcConnected"
61 devEvGrpcDisconnected = "devEvGrpcDisconnected"
62 devEvDeviceUpInd = "devEvDeviceUpInd"
63 devEvDeviceDownInd = "devEvDeviceDownInd"
64)
65const (
66 // states of Device FSM
67 devStNull = "devStNull"
68 devStDown = "devStDown"
69 devStInit = "devStInit"
70 devStConnected = "devStConnected"
71 devStUp = "devStUp"
72)
73
Holger Hildebrandt24d51952020-05-04 14:03:42 +000074//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
75const (
Himani Chawla4d908332020-08-31 12:30:20 +053076 pon = voltha.EventSubCategory_PON
77 //olt = voltha.EventSubCategory_OLT
78 //ont = voltha.EventSubCategory_ONT
79 //onu = voltha.EventSubCategory_ONU
80 //nni = voltha.EventSubCategory_NNI
81 //service = voltha.EventCategory_SERVICE
82 //security = voltha.EventCategory_SECURITY
83 equipment = voltha.EventCategory_EQUIPMENT
84 //processing = voltha.EventCategory_PROCESSING
85 //environment = voltha.EventCategory_ENVIRONMENT
86 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000087)
88
89const (
90 cEventObjectType = "ONU"
91)
92const (
93 cOnuActivatedEvent = "ONU_ACTIVATED"
94)
95
Holger Hildebrandt10d98192021-01-27 15:29:31 +000096type usedOmciConfigFsms int
97
98const (
99 cUploadFsm usedOmciConfigFsms = iota
100 cDownloadFsm
101 cUniLockFsm
102 cUniUnLockFsm
103 cAniConfigFsm
104 cUniVlanConfigFsm
Girish Gowdrae0140f02021-02-02 16:55:09 -0800105 cL2PmFsm
mpagenko80622a52021-02-09 16:53:23 +0000106 cOnuUpgradeFsm
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000107)
108
mpagenkof1fc3862021-02-16 10:09:52 +0000109type omciIdleCheckStruct struct {
110 omciIdleCheckFunc func(*deviceHandler, context.Context, usedOmciConfigFsms, string) bool
111 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000112}
113
mpagenkof1fc3862021-02-16 10:09:52 +0000114var fsmOmciIdleStateFuncMap = map[usedOmciConfigFsms]omciIdleCheckStruct{
115 cUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibUlFsmIdleState},
116 cDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibDlFsmIdleState},
117 cUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
118 cUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
119 cAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, cAniFsmIdleState},
120 cUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, cVlanFsmIdleState},
121 cL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cL2PmFsmIdleState},
mpagenko80622a52021-02-09 16:53:23 +0000122 cOnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cOnuUpgradeFsmIdleState},
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000123}
124
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000125const (
126 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000127 drUnset = 0
128 drActivatingOnu = 1
129 drStartingOpenomci = 2
130 drDiscoveryMibsyncComplete = 3
131 drInitialMibDownloaded = 4
132 drTechProfileConfigDownloadSuccess = 5
133 drOmciFlowsPushed = 6
134 drOmciAdminLock = 7
135 drOnuReenabled = 8
136 drStoppingOpenomci = 9
137 drRebooting = 10
138 drOmciFlowsDeleted = 11
139 drTechProfileConfigDeleteSuccess = 12
Maninder7961d722021-06-16 22:10:28 +0530140 drReconcileFailed = 13
141 drReconcileMaxTimeout = 14
142 drReconcileCanceled = 15
Girish Gowdra50e56422021-06-01 16:46:04 -0700143 drTechProfileConfigDownloadFailed = 16
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000144)
145
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000146var deviceReasonMap = map[uint8]string{
147 drUnset: "unset",
148 drActivatingOnu: "activating-onu",
149 drStartingOpenomci: "starting-openomci",
150 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
151 drInitialMibDownloaded: "initial-mib-downloaded",
152 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
Girish Gowdra50e56422021-06-01 16:46:04 -0700153 drTechProfileConfigDownloadFailed: "tech-profile-config-download-failed",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000154 drOmciFlowsPushed: "omci-flows-pushed",
155 drOmciAdminLock: "omci-admin-lock",
156 drOnuReenabled: "onu-reenabled",
157 drStoppingOpenomci: "stopping-openomci",
158 drRebooting: "rebooting",
159 drOmciFlowsDeleted: "omci-flows-deleted",
160 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
Maninder7961d722021-06-16 22:10:28 +0530161 drReconcileFailed: "reconcile-failed",
162 drReconcileMaxTimeout: "reconcile-max-timeout",
163 drReconcileCanceled: "reconciling-canceled",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000164}
165
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000166const (
167 cNoReconciling = iota
168 cOnuConfigReconciling
169 cSkipOnuConfigReconciling
170)
171
Himani Chawla6d2ae152020-09-02 13:11:20 +0530172//deviceHandler will interact with the ONU ? device.
173type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000174 deviceID string
175 DeviceType string
176 adminState string
177 device *voltha.Device
178 logicalDeviceID string
179 ProxyAddressID string
180 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530181 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000182 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000183
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000184 coreProxy adapterif.CoreProxy
185 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530186 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000187
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800188 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800189
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000190 pOpenOnuAc *OpenONUAC
191 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530192 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000193 deviceEntrySet chan bool //channel for DeviceEntry set event
194 pOnuOmciDevice *OnuDeviceEntry
195 pOnuTP *onuUniTechProf
196 pOnuMetricsMgr *onuMetricsManager
197 pAlarmMgr *onuAlarmManager
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700198 pSelfTestHdlr *selfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000199 exitChannel chan int
200 lockDevice sync.RWMutex
201 pOnuIndication *oop.OnuIndication
202 deviceReason uint8
203 mutexDeviceReason sync.RWMutex
204 pLockStateFsm *lockStateFsm
205 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000206
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000207 //flowMgr *OpenOltFlowMgr
208 //eventMgr *OpenOltEventMgr
209 //resourceMgr *rsrcMgr.OpenOltResourceMgr
210
211 //discOnus sync.Map
212 //onus sync.Map
213 //portStats *OpenOltStatisticsMgr
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000214 collectorIsRunning bool
215 mutexCollectorFlag sync.RWMutex
216 stopCollector chan bool
217 alarmManagerIsRunning bool
218 mutextAlarmManagerFlag sync.RWMutex
219 stopAlarmManager chan bool
220 stopHeartbeatCheck chan bool
221 uniEntityMap map[uint32]*onuUniPort
222 mutexKvStoreContext sync.Mutex
223 lockVlanConfig sync.RWMutex
224 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
225 lockUpgradeFsm sync.RWMutex
226 pOnuUpradeFsm *OnuUpgradeFsm
227 reconciling uint8
228 mutexReconcilingFlag sync.RWMutex
229 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000230 reconcilingFlows bool
231 mutexReconcilingFlowsFlag sync.RWMutex
232 chReconcilingFlowsFinished chan bool //channel to indicate that reconciling of flows has been finished
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000233 mutexReadyForOmciConfig sync.RWMutex
234 readyForOmciConfig bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000235 deletionInProgress bool
236 mutexDeletionInProgressFlag sync.RWMutex
mpagenkoaa3afe92021-05-21 16:20:58 +0000237 upgradeSuccess bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000238}
239
Himani Chawla6d2ae152020-09-02 13:11:20 +0530240//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530241func 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 +0530242 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000243 dh.coreProxy = cp
244 dh.AdapterProxy = ap
245 dh.EventProxy = ep
246 cloned := (proto.Clone(device)).(*voltha.Device)
247 dh.deviceID = cloned.Id
248 dh.DeviceType = cloned.Type
249 dh.adminState = "up"
250 dh.device = cloned
251 dh.pOpenOnuAc = adapter
252 dh.exitChannel = make(chan int, 1)
253 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000254 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000255 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000256 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530257 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530258 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000259 dh.stopHeartbeatCheck = make(chan bool, 2)
260 //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 +0000261 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530262 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000263 dh.lockVlanConfig = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000264 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000265 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000266 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000267 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000268 dh.reconcilingFlows = false
269 dh.chReconcilingFlowsFinished = make(chan bool)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000270 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000271 dh.deletionInProgress = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000272
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800273 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
274 dh.pmConfigs = cloned.PmConfigs
275 } /* else {
276 // will be populated when onu_metrics_mananger is initialized.
277 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800278
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000279 // Device related state machine
280 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000281 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000282 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000283 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
284 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
285 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
286 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
287 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000288 },
289 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000290 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
291 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
292 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
293 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
294 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
295 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
296 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
297 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000298 },
299 )
mpagenkoaf801632020-07-03 10:00:42 +0000300
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000301 return &dh
302}
303
Himani Chawla6d2ae152020-09-02 13:11:20 +0530304// start save the device to the data model
305func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000306 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000307 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000308 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000309}
310
Himani Chawla4d908332020-08-31 12:30:20 +0530311/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000312// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530313func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000314 logger.Debug("stopping-device-handler")
315 dh.exitChannel <- 1
316}
Himani Chawla4d908332020-08-31 12:30:20 +0530317*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000318
319// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530320// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000321
Girish Gowdrae0140f02021-02-02 16:55:09 -0800322//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530323func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000324 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000325
dbainbri4d3a0dc2020-12-02 00:33:42 +0000326 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000327 if dh.pDeviceStateFsm.Is(devStNull) {
328 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000329 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000330 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000331 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800332 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
333 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800334 // Now, set the initial PM configuration for that device
335 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
336 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
337 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800338 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000339 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000340 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000341 }
342
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000343}
344
mpagenko057889c2021-01-21 16:51:58 +0000345func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530346 msgBody := msg.GetBody()
347 omciMsg := &ic.InterAdapterOmciMessage{}
348 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000349 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530350 "device-id": dh.deviceID, "error": err})
351 return err
352 }
353
mpagenko80622a52021-02-09 16:53:23 +0000354 /* 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 +0530355 //assuming omci message content is hex coded!
356 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000357 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530358 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000359 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000360 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530361 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000362 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000363 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000364 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000365 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 +0530366 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000367 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000368 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530369}
370
Himani Chawla6d2ae152020-09-02 13:11:20 +0530371func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000372 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530373 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000374
dbainbri4d3a0dc2020-12-02 00:33:42 +0000375 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000376
dbainbri4d3a0dc2020-12-02 00:33:42 +0000377 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000378 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000379 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000380 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
381 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530382 if dh.pOnuTP == nil {
383 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000384 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530385 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000386 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530387 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000388 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000389 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000390 "device-state": dh.getDeviceReasonString()})
391 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530392 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000393 //previous state test here was just this one, now extended for more states to reject the SetRequest:
394 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
395 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530396
397 msgBody := msg.GetBody()
398 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
399 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000400 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530401 "device-id": dh.deviceID, "error": err})
402 return err
403 }
404
405 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000406 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
407 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530408 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000409 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000410
411 if techProfMsg.UniId > 255 {
412 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
413 techProfMsg.UniId, dh.deviceID))
414 }
415 uniID := uint8(techProfMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700416 tpID, err := GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800417 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700418 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800419 return err
420 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700421 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000422
Girish Gowdra50e56422021-06-01 16:46:04 -0700423 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530424
Girish Gowdra50e56422021-06-01 16:46:04 -0700425 switch tpInst := techProfMsg.TechTpInstance.(type) {
426 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance:
427 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
428 // if there has been some change for some uni TechProfilePath
429 //in order to allow concurrent calls to other dh instances we do not wait for execution here
430 //but doing so we can not indicate problems to the caller (who does what with that then?)
431 //by now we just assume straightforward successful execution
432 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
433 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530434
Girish Gowdra50e56422021-06-01 16:46:04 -0700435 // deadline context to ensure completion of background routines waited for
436 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
437 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
438 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000439
Girish Gowdra50e56422021-06-01 16:46:04 -0700440 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
441
442 var wg sync.WaitGroup
443 wg.Add(1) // for the 1 go routine to finish
444 // attention: deadline completion check and wg.Done is to be done in both routines
445 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
446 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
447 if tpErr := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
448 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.deviceID, "err": tpErr, "tp-path": techProfMsg.TpInstancePath})
449 return tpErr
450 }
451 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
452 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
453 pDevEntry.resetKvProcessingErrorIndication()
454 wg.Add(1) // for the 1 go routine to finish
455 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
456 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
457 if kvErr := pDevEntry.getKvProcessingErrorIndication(); kvErr != nil {
458 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.deviceID, "err": kvErr, "tp-path": techProfMsg.TpInstancePath})
459 return kvErr
460 }
461 return nil
462 default:
463 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"tp-path": techProfMsg.TpInstancePath})
464 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700465 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530466 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000467 // no change, nothing really to do - return success
Girish Gowdra50e56422021-06-01 16:46:04 -0700468 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530469 return nil
470}
471
Himani Chawla6d2ae152020-09-02 13:11:20 +0530472func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000473 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530474 msg *ic.InterAdapterMessage) error {
475
dbainbri4d3a0dc2020-12-02 00:33:42 +0000476 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000477
dbainbri4d3a0dc2020-12-02 00:33:42 +0000478 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000479 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000480 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000481 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
482 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530483 if dh.pOnuTP == nil {
484 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000485 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530486 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000487 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530488 }
489
490 msgBody := msg.GetBody()
491 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
492 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000493 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530494 "device-id": dh.deviceID, "error": err})
495 return err
496 }
497
498 //compare TECH_PROFILE_DOWNLOAD_REQUEST
499 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000500 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530501
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000502 if delGemPortMsg.UniId > 255 {
503 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
504 delGemPortMsg.UniId, dh.deviceID))
505 }
506 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700507 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800508 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700509 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800510 return err
511 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530512
mpagenkofc4f56e2020-11-04 17:17:49 +0000513 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000514
mpagenkofc4f56e2020-11-04 17:17:49 +0000515 // deadline context to ensure completion of background routines waited for
516 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
517 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000518
Girish Gowdra041dcb32020-11-16 16:54:30 -0800519 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000520
mpagenkofc4f56e2020-11-04 17:17:49 +0000521 var wg sync.WaitGroup
522 wg.Add(1) // for the 1 go routine to finish
Girish Gowdra50e56422021-06-01 16:46:04 -0700523 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpInstancePath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000524 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000525 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000526
Girish Gowdra041dcb32020-11-16 16:54:30 -0800527 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530528}
529
Himani Chawla6d2ae152020-09-02 13:11:20 +0530530func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000531 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530532 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000533
dbainbri4d3a0dc2020-12-02 00:33:42 +0000534 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000535
dbainbri4d3a0dc2020-12-02 00:33:42 +0000536 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000537 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000538 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000539 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
540 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530541 if dh.pOnuTP == nil {
542 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000543 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530544 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000545 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530546 }
547
548 msgBody := msg.GetBody()
549 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
550 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000551 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530552 "device-id": dh.deviceID, "error": err})
553 return err
554 }
555
556 //compare TECH_PROFILE_DOWNLOAD_REQUEST
557 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000558 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000559
560 if delTcontMsg.UniId > 255 {
561 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
562 delTcontMsg.UniId, dh.deviceID))
563 }
564 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700565 tpPath := delTcontMsg.TpInstancePath
Girish Gowdra041dcb32020-11-16 16:54:30 -0800566 tpID, err := GetTpIDFromTpPath(tpPath)
567 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000568 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800569 return err
570 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000571
dbainbri4d3a0dc2020-12-02 00:33:42 +0000572 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700573 pDevEntry.freeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530574 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530575 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530576 dctx, cancel := context.WithDeadline(context.Background(), deadline)
577
Girish Gowdra041dcb32020-11-16 16:54:30 -0800578 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000579 pDevEntry.resetKvProcessingErrorIndication()
580
Himani Chawla26e555c2020-08-31 12:30:20 +0530581 var wg sync.WaitGroup
582 wg.Add(2) // for the 2 go routines to finish
Girish Gowdra50e56422021-06-01 16:46:04 -0700583 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpInstancePath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530584 cResourceTcont, delTcontMsg.AllocId, &wg)
585 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000586 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
587 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000588
Girish Gowdra041dcb32020-11-16 16:54:30 -0800589 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530590 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530591 return nil
592}
593
Himani Chawla6d2ae152020-09-02 13:11:20 +0530594//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000595// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
596// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000597func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000598 msgID := msg.Header.Id
599 msgType := msg.Header.Type
600 fromTopic := msg.Header.FromTopic
601 toTopic := msg.Header.ToTopic
602 toDeviceID := msg.Header.ToDeviceId
603 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000604 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000605 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
606
607 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000608 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000609 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
610 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000611 {
mpagenko057889c2021-01-21 16:51:58 +0000612 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000613 }
mpagenkoaf801632020-07-03 10:00:42 +0000614 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
615 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000616 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000617 }
618 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
619 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000620 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000621
mpagenkoaf801632020-07-03 10:00:42 +0000622 }
623 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
624 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000625 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000626 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000627 default:
628 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000629 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000630 "msgType": msg.Header.Type, "device-id": dh.deviceID})
631 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000632 }
633 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000634}
635
mpagenkodff5dda2020-08-28 11:52:01 +0000636//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000637func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
638 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000639 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
ozgecanetsia82b91a62021-05-21 18:54:49 +0300640 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID, "metadata": apFlowMetaData})
mpagenko01e726e2020-10-23 09:45:29 +0000641 var retError error = nil
642 //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 +0000643 if apOfFlowChanges.ToRemove != nil {
644 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000645 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000646 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000647 "device-id": dh.deviceID})
648 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000649 continue
650 }
651 flowInPort := flow.GetInPort(flowItem)
652 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000653 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 +0000654 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
655 continue
656 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000657 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000658 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000659 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000660 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000661 continue
662 } else {
663 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530664 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000665 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
666 loUniPort = uniPort
667 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000668 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000669 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
670 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
671 flowInPort, dh.deviceID)
672 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000673 }
674 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000675 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000676 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000677 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000678 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000679 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000680 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000681 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000682 log.Fields{"device-id": dh.deviceID, "error": err})
683 retError = err
684 continue
685 //return err
686 } else { // if last setting succeeds, overwrite possibly previously set error
687 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000688 }
689 }
690 }
691 }
mpagenko01e726e2020-10-23 09:45:29 +0000692 if apOfFlowChanges.ToAdd != nil {
693 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
694 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000695 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000696 "device-id": dh.deviceID})
697 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
698 continue
699 }
700 flowInPort := flow.GetInPort(flowItem)
701 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000702 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 +0000703 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
704 continue
705 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
706 } else if flowInPort == dh.ponPortNumber {
707 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000708 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000709 "device-id": dh.deviceID, "inPort": flowInPort})
710 continue
711 } else {
712 // this is the relevant upstream flow
713 var loUniPort *onuUniPort
714 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
715 loUniPort = uniPort
716 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000717 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000718 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
719 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
720 flowInPort, dh.deviceID)
721 continue
722 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
723 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000724 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
725 // if not, we just throw some error here to have an indication about that, if we really need to support that
726 // then we would need to create some means to activate the internal stored flows
727 // after the device gets active automatically (and still with its dependency to the TechProfile)
728 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
729 // also abort for the other still possible flows here
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000730 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000731 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000732 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000733 return fmt.Errorf("improper device state on device %s", dh.deviceID)
734 }
735
mpagenko01e726e2020-10-23 09:45:29 +0000736 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000737 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000738 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
739 "uniPortName": loUniPort.name})
ozgecanetsia82b91a62021-05-21 18:54:49 +0300740 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort, apFlowMetaData)
mpagenko01e726e2020-10-23 09:45:29 +0000741 //try next flow after processing error
742 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000743 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000744 log.Fields{"device-id": dh.deviceID, "error": err})
745 retError = err
746 continue
747 //return err
748 } else { // if last setting succeeds, overwrite possibly previously set error
749 retError = nil
750 }
751 }
752 }
753 }
754 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000755}
756
Himani Chawla6d2ae152020-09-02 13:11:20 +0530757//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000758//following are the expected device states after this activity:
759//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
760// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000761func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
762 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000763
mpagenko900ee4b2020-10-12 11:56:34 +0000764 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000765 //note that disableDevice sequences in some 'ONU active' state may yield also
766 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000767 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000768 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000769 //disable-device shall be just a UNi/ONU-G related admin state setting
770 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000771
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000772 if dh.isReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000773 // disable UNI ports/ONU
774 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
775 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000776 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000777 } else { //LockStateFSM already init
778 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000779 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000780 }
781 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000782 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000783 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000784 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000785 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
786 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000787 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000788 }
mpagenko01e726e2020-10-23 09:45:29 +0000789 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000790
791 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000792 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000793 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300794 }
795}
796
Himani Chawla6d2ae152020-09-02 13:11:20 +0530797//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000798func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
799 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000800
mpagenkoaa3afe92021-05-21 16:20:58 +0000801 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000802 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
803 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
804 // for real ONU's that should have nearly no influence
805 // Note that for real ONU's there is anyway a problematic situation with following sequence:
806 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
807 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
808 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000809 dh.setReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000810
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000811 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000812 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000813 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000814 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000815 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000816 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000817 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000818 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300819}
820
dbainbri4d3a0dc2020-12-02 00:33:42 +0000821func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
822 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000823
dbainbri4d3a0dc2020-12-02 00:33:42 +0000824 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000825 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000826 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000827 return
828 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000829 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000830 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000831 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000832 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000833 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000834 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700835 dh.stopReconciling(ctx, false)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000836 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000837 }
Himani Chawla4d908332020-08-31 12:30:20 +0530838 var onuIndication oop.OnuIndication
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000839 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000840 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
841 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
842 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
843 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000844 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000845 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000846}
847
dbainbri4d3a0dc2020-12-02 00:33:42 +0000848func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
849 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000850
dbainbri4d3a0dc2020-12-02 00:33:42 +0000851 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000852 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000853 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000854 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700855 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000856 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000857 return
858 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000859 dh.pOnuTP.lockTpProcMutex()
860 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000861 pDevEntry.mutexPersOnuConfig.RLock()
862 defer pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000863
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000864 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000865 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000866 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000867 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700868 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000869 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000870 return
871 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000872 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700873 techProfsFound := false
874 techProfInstLoadFailed := false
875outerLoop:
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000876 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000877 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
878 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000879 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000880 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000881 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000882 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700883 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800884 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700885 // Request the TpInstance again from the openolt adapter in case of reconcile
886 iaTechTpInst, err := dh.AdapterProxy.TechProfileInstanceRequest(ctx, uniData.PersTpPathMap[tpID],
887 dh.device.ParentPortNo, dh.device.ProxyAddress.OnuId, uint32(uniData.PersUniID),
888 dh.pOpenOnuAc.config.Topic, dh.ProxyAddressType,
889 dh.parentID, dh.ProxyAddressID)
890 if err != nil || iaTechTpInst == nil {
891 logger.Errorw(ctx, "error fetching tp instance",
892 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID, "err": err})
893 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
894 break outerLoop
895 }
896 var tpInst tech_profile.TechProfileInstance
897 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
898 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
899 tpInst = *techTpInst.TpInstance
900 logger.Debugw(ctx, "received-tp-instance-successfully-after-reconcile", log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
901
902 default: // do not support epon or other tech
903 logger.Errorw(ctx, "unsupported-tech", log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
904 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
905 break outerLoop
906 }
907
Girish Gowdra041dcb32020-11-16 16:54:30 -0800908 // deadline context to ensure completion of background routines waited for
909 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
910 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000911 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000912
Girish Gowdra041dcb32020-11-16 16:54:30 -0800913 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
914 var wg sync.WaitGroup
915 wg.Add(1) // for the 1 go routine to finish
Girish Gowdra50e56422021-06-01 16:46:04 -0700916 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000917 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800918 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000919 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700920 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
921 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800922 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000923 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000924 if len(uniData.PersFlowParams) != 0 {
925 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000926 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000927 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000928 if !techProfsFound {
929 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
930 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000931 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700932 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000933 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000934 return
935 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700936 if techProfInstLoadFailed {
937 dh.setDeviceReason(drTechProfileConfigDownloadFailed)
938 dh.stopReconciling(ctx, false)
939 return
940 } else if dh.isSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000941 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
942 }
943 if !flowsFound {
944 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
945 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000946 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700947 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000948 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000949 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000950}
951
dbainbri4d3a0dc2020-12-02 00:33:42 +0000952func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
953 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000954
dbainbri4d3a0dc2020-12-02 00:33:42 +0000955 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000956 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000957 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000958 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700959 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000960 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000961 return
962 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000963 pDevEntry.mutexPersOnuConfig.RLock()
964 defer pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000965
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000966 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000967 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000968 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000969 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700970 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000971 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000972 return
973 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000974 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000975 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000976 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
977 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000978 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000979 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000980 continue
981 }
982 if len(uniData.PersTpPathMap) == 0 {
983 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
984 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000985 // It doesn't make sense to configure any flows if no TPs are available
986 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000987 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000988 var uniPort *onuUniPort
989 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000990 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000991 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000992 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
993 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000994 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700995 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000996 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000997 return
998 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000999 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001000 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001001 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001002 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001003 for _, flowData := range uniData.PersFlowParams {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001004 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 +02001005 // If this is the last flow for the device we need to announce it the waiting
1006 // chReconcilingFlowsFinished channel
1007 if flowsProcessed == len(uniData.PersFlowParams)-1 {
1008 lastFlowToReconcile = true
1009 }
mpagenko01e726e2020-10-23 09:45:29 +00001010 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenko7d14de12021-07-27 08:31:56 +00001011 dh.lockVlanConfig.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001012 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001013 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +00001014 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +03001015 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001016 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001017 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001018 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001019 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00001020 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +03001021 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001022 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001023 }
1024 }
mpagenko7d14de12021-07-27 08:31:56 +00001025 dh.lockVlanConfig.Unlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001026 flowsProcessed++
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001027 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001028 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{"device-id": dh.deviceID, "flowsProcessed": flowsProcessed,
1029 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
1030 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001031 // this can't be used as global finished reconciling flag because
1032 // assumes is getting called before the state machines for the last flow is completed,
1033 // while this is not guaranteed.
1034 //dh.setReconcilingFlows(false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001035 }
1036 if !flowsFound {
1037 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
1038 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001039 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001040 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001041 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001042 return
1043 }
1044 if dh.isSkipOnuConfigReconciling() {
1045 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001046 }
1047}
1048
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001049func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
1050 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001051 dh.stopReconciling(ctx, true)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001052}
1053
dbainbri4d3a0dc2020-12-02 00:33:42 +00001054func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
1055 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001056
dbainbri4d3a0dc2020-12-02 00:33:42 +00001057 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001058 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001059 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +00001060 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001061 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001062 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001063
1064 // deadline context to ensure completion of background routines waited for
1065 //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 +05301066 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001067 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001068
1069 pDevEntry.resetKvProcessingErrorIndication()
1070
1071 var wg sync.WaitGroup
1072 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001073 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1074 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001075
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001076 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001077 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001078}
1079
mpagenko15ff4a52021-03-02 10:09:20 +00001080//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1081// before this change here return like this was used:
1082// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1083//was and is called in background - error return does not make sense
1084func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1085 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1086 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001087 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001088 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001089 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001090 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301091 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001092 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001093 return
Himani Chawla4d908332020-08-31 12:30:20 +05301094 }
mpagenko01e726e2020-10-23 09:45:29 +00001095
1096 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001097 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001098
dbainbri4d3a0dc2020-12-02 00:33:42 +00001099 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001100 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001101 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001102 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001103 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001104 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001105 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001106 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001107 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001108 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001109 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001110 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001111 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1112 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1113 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1114 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001115}
1116
mpagenkoc8bba412021-01-15 15:38:44 +00001117//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +00001118func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1119 apDownloadManager *adapterDownloadManager) error {
1120 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001121 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001122
1123 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001124 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1125 if pDevEntry == nil {
1126 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1127 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1128 }
1129
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001130 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001131 var inactiveImageID uint16
1132 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1133 dh.lockUpgradeFsm.Lock()
1134 defer dh.lockUpgradeFsm.Unlock()
1135 if dh.pOnuUpradeFsm == nil {
1136 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1137 if err == nil {
1138 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1139 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1140 "device-id": dh.deviceID, "error": err})
1141 }
1142 } else {
1143 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001144 "device-id": dh.deviceID, "error": err})
1145 }
mpagenko15ff4a52021-03-02 10:09:20 +00001146 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1147 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1148 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1149 if pUpgradeStatemachine != nil {
1150 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1151 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1152 "device-id": dh.deviceID, "error": err})
1153 }
1154 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1155 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1156 // for now a second start of download should work again
1157 } else { //should never occur
1158 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1159 "device-id": dh.deviceID})
1160 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001161 }
mpagenko80622a52021-02-09 16:53:23 +00001162 }
mpagenko15ff4a52021-03-02 10:09:20 +00001163 } else {
1164 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1165 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001166 }
1167 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001168 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1169 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001170 }
1171 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001172}
1173
mpagenkoc26d4c02021-05-06 14:27:57 +00001174//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1175// after the OnuImage has been downloaded to the adapter, called in background
1176func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
1177 apDownloadManager *fileDownloadManager, aImageIdentifier string) {
1178
1179 var err error
1180 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1181 if pDevEntry == nil {
1182 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1183 return
1184 }
1185
1186 var inactiveImageID uint16
1187 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1188 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
1189 "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
1190 dh.lockUpgradeFsm.Lock()
1191 defer dh.lockUpgradeFsm.Unlock()
1192 if dh.pOnuUpradeFsm == nil {
1193 //OmciOnuSwUpgradeDone could be used to create some Kafka event with information on upgrade completion,
1194 // but none yet defined
1195 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1196 if err == nil {
1197 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
Holger Hildebrandtac010732021-06-02 13:35:39 +00001198 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00001199 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1200 "device-id": dh.deviceID, "error": err})
1201 return
1202 }
1203 } else {
1204 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1205 "device-id": dh.deviceID, "error": err})
1206 }
1207 return
1208 }
1209 //OnuSw upgrade already running - restart (with possible abort of running)
1210 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1211 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1212 if pUpgradeStatemachine != nil {
1213 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1214 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1215 "device-id": dh.deviceID, "error": err})
1216 return
1217 }
1218 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1219 // for now a second start of download should work again - must still be initiated by user
1220 } else { //should never occur
1221 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1222 "device-id": dh.deviceID})
1223 }
1224 return
1225 }
1226 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1227 "device-id": dh.deviceID, "error": err})
1228}
1229
1230//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001231func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1232 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001233 var err error
1234 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1235 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1236 // 2.) activation of the inactive image
1237
1238 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1239 if pDevEntry == nil {
1240 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001241 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001242 }
1243 dh.lockUpgradeFsm.RLock()
1244 if dh.pOnuUpradeFsm != nil {
1245 dh.lockUpgradeFsm.RUnlock()
1246 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1247 dh.deviceID, dh.deviceID)
1248 if getErr != nil || onuVolthaDevice == nil {
1249 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 +00001250 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001251 }
1252 // use the OnuVendor identification from this device for the internal unique name
1253 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1254 // 1.) check a started upgrade process and rely the activation request to it
1255 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001256 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001257 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1258 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001259 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001260 }
mpagenko183647c2021-06-08 15:25:04 +00001261 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1262 "device-id": dh.deviceID, "image-id": imageIdentifier})
1263 var pImageStates *voltha.ImageState
1264 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1265 pImageStates = &voltha.ImageState{}
1266 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1267 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1268 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1269 }
1270 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001271 } //else
1272 dh.lockUpgradeFsm.RUnlock()
1273
1274 // 2.) check if requested image-version equals the inactive one and start its activation
1275 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1276 var inactiveImageID uint16
1277 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1278 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1279 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
mpagenko183647c2021-06-08 15:25:04 +00001280 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001281 }
1282 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1283 if err == nil {
1284 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1285 inactiveImageID, aCommitRequest); err != nil {
1286 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1287 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001288 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001289 }
1290 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1291 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001292 var pImageStates *voltha.ImageState
1293 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1294 pImageStates := &voltha.ImageState{}
1295 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1296 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1297 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1298 }
1299 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001300 } //else
1301 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1302 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001303 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001304}
1305
1306//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001307func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1308 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001309 var err error
1310 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1311 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1312 // 2.) commitment of the active image
1313
1314 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1315 if pDevEntry == nil {
1316 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001317 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001318 }
1319 dh.lockUpgradeFsm.RLock()
1320 if dh.pOnuUpradeFsm != nil {
1321 dh.lockUpgradeFsm.RUnlock()
1322 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1323 dh.deviceID, dh.deviceID)
1324 if getErr != nil || onuVolthaDevice == nil {
1325 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 +00001326 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001327 }
1328 // use the OnuVendor identification from this device for the internal unique name
1329 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1330 // 1.) check a started upgrade process and rely the commitment request to it
1331 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001332 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001333 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1334 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001335 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001336 }
mpagenko183647c2021-06-08 15:25:04 +00001337 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1338 "device-id": dh.deviceID, "image-id": imageIdentifier})
1339 var pImageStates *voltha.ImageState
1340 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1341 pImageStates := &voltha.ImageState{}
1342 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1343 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1344 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1345 }
1346 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001347 } //else
1348 dh.lockUpgradeFsm.RUnlock()
1349
mpagenko183647c2021-06-08 15:25:04 +00001350 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001351 var activeImageID uint16
1352 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1353 logger.Errorw(ctx, "get active image failed", log.Fields{
1354 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
mpagenko183647c2021-06-08 15:25:04 +00001355 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001356 }
1357 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1358 if err == nil {
1359 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1360 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1361 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001362 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001363 }
1364 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1365 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001366 var pImageStates *voltha.ImageState
1367 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1368 pImageStates := &voltha.ImageState{}
1369 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1370 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1371 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1372 }
1373 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001374 } //else
1375 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1376 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001377 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001378}
1379
mpagenkoaa3afe92021-05-21 16:20:58 +00001380func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
1381 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1382 pDeviceImageState.DeviceId = dh.deviceID
mpagenko183647c2021-06-08 15:25:04 +00001383 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001384 dh.lockUpgradeFsm.RLock()
1385 if dh.pOnuUpradeFsm != nil {
1386 dh.lockUpgradeFsm.RUnlock()
mpagenko183647c2021-06-08 15:25:04 +00001387 if pImageStates, err := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion); err == nil {
mpagenkoaa3afe92021-05-21 16:20:58 +00001388 pDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
1389 pDeviceImageState.ImageState.Reason = pImageStates.Reason
1390 pDeviceImageState.ImageState.ImageState = pImageStates.ImageState
1391 } else {
1392 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1393 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1394 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1395 }
1396 } else {
1397 dh.lockUpgradeFsm.RUnlock()
1398 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1399 if dh.upgradeSuccess {
1400 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
1401 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMITTED
1402 } else {
1403 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1404 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1405 }
1406 }
1407}
1408
1409func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1410 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1411 pDeviceImageState.DeviceId = dh.deviceID
mpagenko7455fd42021-06-10 16:25:55 +00001412 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001413 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1414 dh.lockUpgradeFsm.RLock()
1415 if dh.pOnuUpradeFsm != nil {
1416 dh.lockUpgradeFsm.RUnlock()
1417 //option: it could be also checked if the upgrade FSM is running on the given imageIdentifier or version
1418 // by now just straightforward assume this to be true
1419 dh.pOnuUpradeFsm.CancelProcessing(ctx)
1420 //nolint:misspell
1421 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
1422 //nolint:misspell
1423 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1424 } else {
1425 dh.lockUpgradeFsm.RUnlock()
1426 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1427 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1428 }
1429}
1430
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001431func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1432
1433 var onuImageStatus *OnuImageStatus
1434
1435 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1436 if pDevEntry != nil {
1437 onuImageStatus = NewOnuImageStatus(pDevEntry)
1438 pDevEntry.mutexOnuImageStatus.Lock()
1439 pDevEntry.pOnuImageStatus = onuImageStatus
1440 pDevEntry.mutexOnuImageStatus.Unlock()
1441
1442 } else {
1443 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1444 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1445 }
1446 images, err := onuImageStatus.getOnuImageStatus(ctx)
1447 pDevEntry.mutexOnuImageStatus.Lock()
1448 pDevEntry.pOnuImageStatus = nil
1449 pDevEntry.mutexOnuImageStatus.Unlock()
1450 return images, err
1451}
1452
Himani Chawla6d2ae152020-09-02 13:11:20 +05301453// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001454// #####################################################################################
1455
1456// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301457// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001458
dbainbri4d3a0dc2020-12-02 00:33:42 +00001459func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1460 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 +00001461}
1462
1463// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001464func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001465
dbainbri4d3a0dc2020-12-02 00:33:42 +00001466 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001467 var err error
1468
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001469 // populate what we know. rest comes later after mib sync
1470 dh.device.Root = false
1471 dh.device.Vendor = "OpenONU"
1472 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001473 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001474 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001475
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001476 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001477
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001478 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001479 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1480 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301481 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001482 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001483 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001484 log.Fields{"device-id": dh.deviceID})
1485 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001486
Himani Chawla4d908332020-08-31 12:30:20 +05301487 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001488 dh.ponPortNumber = dh.device.ParentPortNo
1489
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001490 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1491 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1492 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001493 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001494 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301495 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001496
1497 /*
1498 self._pon = PonPort.create(self, self._pon_port_number)
1499 self._pon.add_peer(self.parent_id, self._pon_port_number)
1500 self.logger.debug('adding-pon-port-to-agent',
1501 type=self._pon.get_port().type,
1502 admin_state=self._pon.get_port().admin_state,
1503 oper_status=self._pon.get_port().oper_status,
1504 )
1505 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001506 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001507 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001508 var ponPortNo uint32 = 1
1509 if dh.ponPortNumber != 0 {
1510 ponPortNo = dh.ponPortNumber
1511 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001512
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001513 pPonPort := &voltha.Port{
1514 PortNo: ponPortNo,
1515 Label: fmt.Sprintf("pon-%d", ponPortNo),
1516 Type: voltha.Port_PON_ONU,
1517 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301518 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001519 PortNo: ponPortNo}}, // Peer port is parent's port number
1520 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001521 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1522 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001523 e.Cancel(err)
1524 return
1525 }
1526 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001527 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001528 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001529 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001530}
1531
1532// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001533func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001534
dbainbri4d3a0dc2020-12-02 00:33:42 +00001535 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001536 var err error
1537 /*
1538 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1539 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1540 return nil
1541 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001542 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1543 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001544 e.Cancel(err)
1545 return
1546 }
1547
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001548 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001549 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001550 // reconcilement will be continued after mib download is done
1551 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001552
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001553 /*
1554 ############################################################################
1555 # Setup Alarm handler
1556 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1557 device.serial_number)
1558 ############################################################################
1559 # Setup PM configuration for this device
1560 # Pass in ONU specific options
1561 kwargs = {
1562 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1563 'heartbeat': self.heartbeat,
1564 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1565 }
1566 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1567 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1568 self.logical_device_id, device.serial_number,
1569 grouped=True, freq_override=False, **kwargs)
1570 pm_config = self._pm_metrics.make_proto()
1571 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1572 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1573 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1574
1575 # Note, ONU ID and UNI intf set in add_uni_port method
1576 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1577 ani_ports=[self._pon])
1578
1579 # Code to Run OMCI Test Action
1580 kwargs_omci_test_action = {
1581 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1582 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1583 }
1584 serial_number = device.serial_number
1585 self._test_request = OmciTestRequest(self.core_proxy,
1586 self.omci_agent, self.device_id,
1587 AniG, serial_number,
1588 self.logical_device_id,
1589 exclusive=False,
1590 **kwargs_omci_test_action)
1591
1592 self.enabled = True
1593 else:
1594 self.logger.info('onu-already-activated')
1595 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001596
dbainbri4d3a0dc2020-12-02 00:33:42 +00001597 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001598}
1599
1600// doStateConnected get the device info and update to voltha core
1601// for comparison of the original method (not that easy to uncomment): compare here:
1602// voltha-openolt-adapter/adaptercore/device_handler.go
1603// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001604func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001605
dbainbri4d3a0dc2020-12-02 00:33:42 +00001606 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301607 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001608 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001609 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001610}
1611
1612// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001613func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001614
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301616 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001617 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001618 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001619
1620 /*
1621 // Synchronous call to update device state - this method is run in its own go routine
1622 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1623 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001624 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 +00001625 return err
1626 }
1627 return nil
1628 */
1629}
1630
1631// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001632func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001633
dbainbri4d3a0dc2020-12-02 00:33:42 +00001634 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001635 var err error
1636
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001637 device := dh.device
1638 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001639 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001640 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001641 e.Cancel(err)
1642 return
1643 }
1644
1645 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001646 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001647 /*
1648 // Update the all ports state on that device to disable
1649 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001650 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001651 return er
1652 }
1653
1654 //Update the device oper state and connection status
1655 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1656 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1657 dh.device = cloned
1658
1659 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001660 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001661 return er
1662 }
1663
1664 //get the child device for the parent device
1665 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1666 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001667 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001668 return err
1669 }
1670 for _, onuDevice := range onuDevices.Items {
1671
1672 // Update onu state as down in onu adapter
1673 onuInd := oop.OnuIndication{}
1674 onuInd.OperState = "down"
1675 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1676 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1677 if er != nil {
1678 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001679 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001680 //Do not return here and continue to process other ONUs
1681 }
1682 }
1683 // * Discovered ONUs entries need to be cleared , since after OLT
1684 // is up, it starts sending discovery indications again* /
1685 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001686 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001687 return nil
1688 */
Himani Chawla4d908332020-08-31 12:30:20 +05301689 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001690 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001691 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001692}
1693
Himani Chawla6d2ae152020-09-02 13:11:20 +05301694// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001695// #################################################################################
1696
1697// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301698// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001699
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001700//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001701func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001702 dh.lockDevice.RLock()
1703 pOnuDeviceEntry := dh.pOnuOmciDevice
1704 if aWait && pOnuDeviceEntry == nil {
1705 //keep the read sema short to allow for subsequent write
1706 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001707 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001708 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1709 // so it might be needed to wait here for that event with some timeout
1710 select {
1711 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001712 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001713 return nil
1714 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001715 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001716 // if written now, we can return the written value without sema
1717 return dh.pOnuOmciDevice
1718 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001719 }
mpagenko3af1f032020-06-10 08:53:41 +00001720 dh.lockDevice.RUnlock()
1721 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001722}
1723
Himani Chawla6d2ae152020-09-02 13:11:20 +05301724//setOnuDeviceEntry sets the ONU device entry within the handler
1725func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001726 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001727 dh.lockDevice.Lock()
1728 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001729 dh.pOnuOmciDevice = apDeviceEntry
1730 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001731 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301732 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001733 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001734}
1735
Himani Chawla6d2ae152020-09-02 13:11:20 +05301736//addOnuDeviceEntry creates a new ONU device or returns the existing
1737func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001738 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001739
dbainbri4d3a0dc2020-12-02 00:33:42 +00001740 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001741 if deviceEntry == nil {
1742 /* costum_me_map in python code seems always to be None,
1743 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1744 /* also no 'clock' argument - usage open ...*/
1745 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001746 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001747 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001748 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301749 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001750 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001751 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001752 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001753 // fire deviceEntry ready event to spread to possibly waiting processing
1754 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001755 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001756 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001757 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001758 }
1759 // might be updated with some error handling !!!
1760 return nil
1761}
1762
dbainbri4d3a0dc2020-12-02 00:33:42 +00001763func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1764 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001765 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1766
1767 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001768
dbainbri4d3a0dc2020-12-02 00:33:42 +00001769 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001770 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001771 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001772 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1773 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001774 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001775 if err := dh.storePersistentData(ctx); err != nil {
1776 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001777 log.Fields{"device-id": dh.deviceID, "err": err})
1778 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001779 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001780 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001781 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001782 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1783 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001784 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001785 }
1786 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001787 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001788 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001789
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001790 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001791 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001792 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001793 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 +00001794 log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001795 dh.stopReconciling(ctx, true)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001796 } else {
1797 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001798 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001799 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001800 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1801 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1802 // 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 +00001803 // 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 +00001804 // so let's just try to keep it simple ...
1805 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001806 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001807 if err != nil || device == nil {
1808 //TODO: needs to handle error scenarios
1809 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1810 return errors.New("Voltha Device not found")
1811 }
1812 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001813
dbainbri4d3a0dc2020-12-02 00:33:42 +00001814 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001815 return err
mpagenko3af1f032020-06-10 08:53:41 +00001816 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001817
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001818 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001819
1820 /* this might be a good time for Omci Verify message? */
1821 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001822 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001823 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001824 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001825 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001826
1827 /* give the handler some time here to wait for the OMCi verification result
1828 after Timeout start and try MibUpload FSM anyway
1829 (to prevent stopping on just not supported OMCI verification from ONU) */
1830 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001831 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001832 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001833 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001834 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001835 }
1836
1837 /* In py code it looks earlier (on activate ..)
1838 # Code to Run OMCI Test Action
1839 kwargs_omci_test_action = {
1840 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1841 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1842 }
1843 serial_number = device.serial_number
1844 self._test_request = OmciTestRequest(self.core_proxy,
1845 self.omci_agent, self.device_id,
1846 AniG, serial_number,
1847 self.logical_device_id,
1848 exclusive=False,
1849 **kwargs_omci_test_action)
1850 ...
1851 # Start test requests after a brief pause
1852 if not self._test_request_started:
1853 self._test_request_started = True
1854 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1855 reactor.callLater(tststart, self._test_request.start_collector)
1856
1857 */
1858 /* which is then: in omci_test_request.py : */
1859 /*
1860 def start_collector(self, callback=None):
1861 """
1862 Start the collection loop for an adapter if the frequency > 0
1863
1864 :param callback: (callable) Function to call to collect PM data
1865 """
1866 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1867 if callback is None:
1868 callback = self.perform_test_omci
1869
1870 if self.lc is None:
1871 self.lc = LoopingCall(callback)
1872
1873 if self.default_freq > 0:
1874 self.lc.start(interval=self.default_freq / 10)
1875
1876 def perform_test_omci(self):
1877 """
1878 Perform the initial test request
1879 """
1880 ani_g_entities = self._device.configuration.ani_g_entities
1881 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1882 is not None else None
1883 self._entity_id = ani_g_entities_ids[0]
1884 self.logger.info('perform-test', entity_class=self._entity_class,
1885 entity_id=self._entity_id)
1886 try:
1887 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1888 result = yield self._device.omci_cc.send(frame)
1889 if not result.fields['omci_message'].fields['success_code']:
1890 self.logger.info('Self-Test Submitted Successfully',
1891 code=result.fields[
1892 'omci_message'].fields['success_code'])
1893 else:
1894 raise TestFailure('Test Failure: {}'.format(
1895 result.fields['omci_message'].fields['success_code']))
1896 except TimeoutError as e:
1897 self.deferred.errback(failure.Failure(e))
1898
1899 except Exception as e:
1900 self.logger.exception('perform-test-Error', e=e,
1901 class_id=self._entity_class,
1902 entity_id=self._entity_id)
1903 self.deferred.errback(failure.Failure(e))
1904
1905 */
1906
1907 // PM related heartbeat??? !!!TODO....
1908 //self._heartbeat.enabled = True
1909
mpagenko1cc3cb42020-07-27 15:24:38 +00001910 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1911 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1912 * 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 +05301913 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001914 */
1915 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001916 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001917 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001918 if pMibUlFsm.Is(ulStDisabled) {
1919 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001920 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 +00001921 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301922 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001923 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301924 //Determine ONU status and start/re-start MIB Synchronization tasks
1925 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001926 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301927 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001928 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 +00001929 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001930 }
Himani Chawla4d908332020-08-31 12:30:20 +05301931 } else {
1932 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001933 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 +00001934 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301935 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001936 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001937 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001938 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001939 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001940 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001941 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001942 }
1943 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001944 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001945 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001946 }
1947 return nil
1948}
1949
dbainbri4d3a0dc2020-12-02 00:33:42 +00001950func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001951 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001952 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001953 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001954 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001955
mpagenko900ee4b2020-10-12 11:56:34 +00001956 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1957 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1958 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001959 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001960 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001961 log.Fields{"device-id": dh.deviceID, "error": err})
1962 // abort: system behavior is just unstable ...
1963 return err
1964 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001965 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001966 _ = 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 +00001967
1968 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1969 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1970 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001971 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001972 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001974 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001975 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001976 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001977
1978 //TODO!!! remove existing traffic profiles
1979 /* from py code, if TP's exist, remove them - not yet implemented
1980 self._tp = dict()
1981 # Let TP download happen again
1982 for uni_id in self._tp_service_specific_task:
1983 self._tp_service_specific_task[uni_id].clear()
1984 for uni_id in self._tech_profile_download_done:
1985 self._tech_profile_download_done[uni_id].clear()
1986 */
1987
dbainbri4d3a0dc2020-12-02 00:33:42 +00001988 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001989
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001990 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00001991
dbainbri4d3a0dc2020-12-02 00:33:42 +00001992 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001993 // abort: system behavior is just unstable ...
1994 return err
1995 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001996 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001997 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001998 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001999 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002000 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002001 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00002002 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002003 // abort: system behavior is just unstable ...
2004 return err
2005 }
2006 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002007 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002008 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002009 return nil
2010}
2011
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002012func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002013 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2014 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2015 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2016 // and using the stop/reset event should never harm
2017
dbainbri4d3a0dc2020-12-02 00:33:42 +00002018 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002019 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002020 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002021 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2022 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002023 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002024 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002025 }
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002026 pDevEntry.mutexOnuImageStatus.RLock()
2027 if pDevEntry.pOnuImageStatus != nil {
2028 pDevEntry.pOnuImageStatus.CancelProcessing(ctx)
2029 }
2030 pDevEntry.mutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002031
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002032 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002033 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002034 }
2035 //MibDownload may run
2036 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2037 if pMibDlFsm != nil {
2038 _ = pMibDlFsm.Event(dlEvReset)
2039 }
2040 //port lock/unlock FSM's may be active
2041 if dh.pUnlockStateFsm != nil {
2042 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2043 }
2044 if dh.pLockStateFsm != nil {
2045 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2046 }
2047 //techProfile related PonAniConfigFsm FSM may be active
2048 if dh.pOnuTP != nil {
2049 // should always be the case here
2050 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
2051 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08002052 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00002053 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002054 }
mpagenko900ee4b2020-10-12 11:56:34 +00002055 }
2056 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002057 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002058 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00002059 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
2060 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002061 dh.lockVlanConfig.RUnlock()
2062 //reset of all Fsm is always accompanied by global persistency data removal
2063 // no need to remove specific data
2064 pVlanFilterFsm.RequestClearPersistency(false)
2065 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002066 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002067 } else {
2068 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002069 }
2070 }
2071 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002072 if dh.getCollectorIsRunning() {
2073 // Stop collector routine
2074 dh.stopCollector <- true
2075 }
Himani Chawla1472c682021-03-17 17:11:14 +05302076 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302077 dh.stopAlarmManager <- true
2078 }
2079
mpagenko80622a52021-02-09 16:53:23 +00002080 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00002081 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002082 dh.lockUpgradeFsm.RLock()
2083 if dh.pOnuUpradeFsm != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00002084 dh.pOnuUpradeFsm.CancelProcessing(ctx)
mpagenko80622a52021-02-09 16:53:23 +00002085 }
2086 dh.lockUpgradeFsm.RUnlock()
2087
mpagenko7d6bb022021-03-11 15:07:55 +00002088 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002089 return nil
2090}
2091
dbainbri4d3a0dc2020-12-02 00:33:42 +00002092func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2093 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 +05302094
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002095 // store persistent data collected during MIB upload processing
2096 if err := dh.storePersistentData(ctx); err != nil {
2097 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2098 log.Fields{"device-id": dh.deviceID, "err": err})
2099 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002100 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002101 dh.addAllUniPorts(ctx)
2102
mpagenkoa40e99a2020-11-17 13:50:39 +00002103 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2104 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2105 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2106 * disable/enable toggling here to allow traffic
2107 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2108 * like the py comment says:
2109 * # start by locking all the unis till mib sync and initial mib is downloaded
2110 * # this way we can capture the port down/up events when we are ready
2111 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302112
mpagenkoa40e99a2020-11-17 13:50:39 +00002113 // Init Uni Ports to Admin locked state
2114 // *** should generate UniLockStateDone event *****
2115 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002116 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002117 } else { //LockStateFSM already init
2118 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002119 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002120 }
2121}
2122
dbainbri4d3a0dc2020-12-02 00:33:42 +00002123func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2124 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302125 /* Mib download procedure -
2126 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2127 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002128 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002129 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002130 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002131 return
2132 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302133 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2134 if pMibDlFsm != nil {
2135 if pMibDlFsm.Is(dlStDisabled) {
2136 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002137 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 +05302138 // maybe try a FSM reset and then again ... - TODO!!!
2139 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002140 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302141 // maybe use more specific states here for the specific download steps ...
2142 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002143 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302144 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002145 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302146 //Begin MIB data download (running autonomously)
2147 }
2148 }
2149 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002150 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002151 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302152 // maybe try a FSM reset and then again ... - TODO!!!
2153 }
2154 /***** Mib download started */
2155 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002156 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302157 }
2158}
2159
dbainbri4d3a0dc2020-12-02 00:33:42 +00002160func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2161 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302162 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002163 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002164 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002165 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002166 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2167 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2168 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2169 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002170 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302171 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
2172 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002173 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302174 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002175 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302176 }
2177 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002178 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302179 log.Fields{"device-id": dh.deviceID})
2180 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002181 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002182
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002183 if !dh.getCollectorIsRunning() {
2184 // Start PM collector routine
2185 go dh.startCollector(ctx)
2186 }
2187 if !dh.getAlarmManagerIsRunning(ctx) {
2188 go dh.startAlarmManager(ctx)
2189 }
2190
Girish Gowdrae0140f02021-02-02 16:55:09 -08002191 // Initialize classical L2 PM Interval Counters
2192 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2193 // There is no way we should be landing here, but if we do then
2194 // there is nothing much we can do about this other than log error
2195 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2196 }
2197
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002198 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002199
2200 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2201 if pDevEntry == nil {
2202 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2203 return
2204 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002205 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002206 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002207 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002208 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2209 log.Fields{"device-id": dh.deviceID})
2210 go dh.reconcileDeviceTechProf(ctx)
2211 // reconcilement will be continued after ani config is done
2212 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002213 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002214 // *** should generate UniUnlockStateDone event *****
2215 if dh.pUnlockStateFsm == nil {
2216 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2217 } else { //UnlockStateFSM already init
2218 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2219 dh.runUniLockFsm(ctx, false)
2220 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302221 }
2222}
2223
dbainbri4d3a0dc2020-12-02 00:33:42 +00002224func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2225 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302226
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002227 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002228 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002229 raisedTs := time.Now().Unix()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002230 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2231 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002232 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002233 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002234 return
2235 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002236 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002237 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002238 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002239 if err := dh.storePersistentData(ctx); err != nil {
2240 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002241 log.Fields{"device-id": dh.deviceID, "err": err})
2242 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302243 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002244 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 +05302245 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002246 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002247 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302248 }
2249}
2250
dbainbri4d3a0dc2020-12-02 00:33:42 +00002251func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2252 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002253 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002254 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00002255 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
2256 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002257 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002258 }
2259
dbainbri4d3a0dc2020-12-02 00:33:42 +00002260 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002261 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002262 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002263
2264 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002265 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002266
dbainbri4d3a0dc2020-12-02 00:33:42 +00002267 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002268 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002269 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002270 return
2271 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002272 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002273 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002274 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002275 if err := dh.storePersistentData(ctx); err != nil {
2276 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002277 log.Fields{"device-id": dh.deviceID, "err": err})
2278 }
mpagenko900ee4b2020-10-12 11:56:34 +00002279}
2280
dbainbri4d3a0dc2020-12-02 00:33:42 +00002281func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2282 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002283 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002284 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002285 voltha.OperStatus_ACTIVE); err != nil {
2286 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002287 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002288 }
2289
dbainbri4d3a0dc2020-12-02 00:33:42 +00002290 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002291 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002292 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002293 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002294
2295 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002296 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002297
dbainbri4d3a0dc2020-12-02 00:33:42 +00002298 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002299 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002300 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002301 return
2302 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002303 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002304 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002305 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002306 if err := dh.storePersistentData(ctx); err != nil {
2307 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002308 log.Fields{"device-id": dh.deviceID, "err": err})
2309 }
mpagenko900ee4b2020-10-12 11:56:34 +00002310}
2311
dbainbri4d3a0dc2020-12-02 00:33:42 +00002312func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002313 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002314 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002315 // attention: the device reason update is done based on ONU-UNI-Port related activity
2316 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002317 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002318 // 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 +00002319 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302320 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002321 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002322 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002323 }
2324 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002325 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002326 // attention: the device reason update is done based on ONU-UNI-Port related activity
2327 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002328 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002329 // 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 +00002330 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002331 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002332 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302333}
2334
dbainbri4d3a0dc2020-12-02 00:33:42 +00002335func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2336 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002337 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302338 // attention: the device reason update is done based on ONU-UNI-Port related activity
2339 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302340
mpagenkof1fc3862021-02-16 10:09:52 +00002341 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002342 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002343 // which may be the case from some previous actvity on another UNI Port of the ONU
2344 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002345 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2346 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002347 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002348 }
2349 }
2350 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002351 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002352 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002353 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002354 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302355 }
mpagenkof1fc3862021-02-16 10:09:52 +00002356
2357 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2358 //events that request KvStore write
2359 if err := dh.storePersistentData(ctx); err != nil {
2360 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2361 log.Fields{"device-id": dh.deviceID, "err": err})
2362 }
2363 } else {
2364 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2365 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002366 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302367}
2368
Himani Chawla6d2ae152020-09-02 13:11:20 +05302369//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002370func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302371 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002372 case MibDatabaseSync:
2373 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002374 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002375 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002376 case UniLockStateDone:
2377 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002378 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002379 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002380 case MibDownloadDone:
2381 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002382 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002383 }
2384 case UniUnlockStateDone:
2385 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002386 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002387 }
mpagenko900ee4b2020-10-12 11:56:34 +00002388 case UniEnableStateDone:
2389 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002390 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002391 }
2392 case UniDisableStateDone:
2393 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002394 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002395 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002396 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002397 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002398 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002399 }
mpagenkof1fc3862021-02-16 10:09:52 +00002400 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002401 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002402 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002403 }
mpagenkoaa3afe92021-05-21 16:20:58 +00002404 case OmciOnuSwUpgradeDone:
2405 {
2406 dh.upgradeSuccess = true
2407 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002408 default:
2409 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002410 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002411 }
2412 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002413}
2414
dbainbri4d3a0dc2020-12-02 00:33:42 +00002415func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002416 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002417 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302418 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002419 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002420 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002421 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302422 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002423 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002424 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002425 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002426 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002427 //store UniPort with the System-PortNumber key
2428 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002429 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002430 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002431 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2432 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002433 } //error logging already within UniPort method
2434 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002435 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002436 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002437 }
2438 }
2439}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002440
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002441func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2442 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2443 if pDevEntry == nil {
2444 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2445 return
2446 }
2447 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2448 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2449 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2450 for _, mgmtEntityID := range pptpInstKeys {
2451 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2452 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2453 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2454 i++
2455 }
2456 } else {
2457 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2458 }
2459 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2460 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2461 for _, mgmtEntityID := range veipInstKeys {
2462 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2463 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2464 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2465 i++
2466 }
2467 } else {
2468 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2469 }
2470 if i == 0 {
2471 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2472 }
2473}
2474
mpagenko3af1f032020-06-10 08:53:41 +00002475// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002476func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002477 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302478 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002479 // with following remark:
2480 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2481 // # load on the core
2482
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002483 // 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 +00002484
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002485 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002486 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002487 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002488 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302489 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002490 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002491 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002492 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 +00002493 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002494 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002495 }
mpagenko3af1f032020-06-10 08:53:41 +00002496 }
2497 }
2498}
2499
2500// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002501func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002502 // compare enableUniPortStateUpdate() above
2503 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2504 for uniNo, uniPort := range dh.uniEntityMap {
2505 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002506
2507 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002508 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302509 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002510 if !dh.isReconciling() {
2511 //maybe also use getter functions on uniPort - perhaps later ...
2512 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2513 } else {
2514 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2515 }
2516
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002517 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002518 }
2519}
2520
2521// ONU_Active/Inactive announcement on system KAFKA bus
2522// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002523func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002524 var de voltha.DeviceEvent
2525 eventContext := make(map[string]string)
2526 //Populating event context
2527 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002528 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002529 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002530 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302531 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002532 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 +00002533 }
2534 oltSerialNumber := parentDevice.SerialNumber
2535
2536 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2537 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2538 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302539 eventContext["olt-serial-number"] = oltSerialNumber
2540 eventContext["device-id"] = aDeviceID
2541 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002542 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
2543 if deviceEntry := dh.getOnuDeviceEntry(ctx, false); deviceEntry != nil {
2544 deviceEntry.mutexPersOnuConfig.RLock()
2545 eventContext["equipment-id"] = deviceEntry.sOnuPersistentData.PersEquipmentID
2546 deviceEntry.mutexPersOnuConfig.RUnlock()
2547 eventContext["software-version"] = deviceEntry.getActiveImageVersion(ctx)
2548 deviceEntry.mutexPersOnuConfig.RLock()
2549 eventContext["vendor"] = deviceEntry.sOnuPersistentData.PersVendorID
2550 deviceEntry.mutexPersOnuConfig.RUnlock()
2551 eventContext["inactive-software-version"] = deviceEntry.getInactiveImageVersion(ctx)
2552 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2553 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2554 } else {
2555 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2556 log.Fields{"device-id": aDeviceID})
2557 return
2558 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002559
2560 /* Populating device event body */
2561 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302562 de.ResourceId = aDeviceID
2563 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002564 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2565 de.Description = fmt.Sprintf("%s Event - %s - %s",
2566 cEventObjectType, cOnuActivatedEvent, "Raised")
2567 } else {
2568 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2569 de.Description = fmt.Sprintf("%s Event - %s - %s",
2570 cEventObjectType, cOnuActivatedEvent, "Cleared")
2571 }
2572 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002573 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2574 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302575 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002576 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002577 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302578 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002579}
2580
Himani Chawla4d908332020-08-31 12:30:20 +05302581// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002582func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002583 chLSFsm := make(chan Message, 2048)
2584 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302585 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002586 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002587 sFsmName = "LockStateFSM"
2588 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002589 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002590 sFsmName = "UnLockStateFSM"
2591 }
mpagenko3af1f032020-06-10 08:53:41 +00002592
dbainbri4d3a0dc2020-12-02 00:33:42 +00002593 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002594 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002595 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002596 return
2597 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002598 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002599 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002600 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302601 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002602 dh.pLockStateFsm = pLSFsm
2603 } else {
2604 dh.pUnlockStateFsm = pLSFsm
2605 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002606 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002607 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002608 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002609 }
2610}
2611
2612// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002613func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002614 /* Uni Port lock/unlock procedure -
2615 ***** should run via 'adminDone' state and generate the argument requested event *****
2616 */
2617 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302618 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002619 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2620 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2621 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002622 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302623 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002624 }
2625 } else {
2626 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2627 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2628 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002629 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302630 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002631 }
2632 }
2633 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002634 if pLSStatemachine.Is(uniStDisabled) {
2635 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002636 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002637 // maybe try a FSM reset and then again ... - TODO!!!
2638 } else {
2639 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002640 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002641 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002642 }
2643 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002644 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002645 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002646 // maybe try a FSM reset and then again ... - TODO!!!
2647 }
2648 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002649 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002650 // maybe try a FSM reset and then again ... - TODO!!!
2651 }
2652}
2653
mpagenko80622a52021-02-09 16:53:23 +00002654// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002655func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002656 //in here lockUpgradeFsm is already locked
2657 chUpgradeFsm := make(chan Message, 2048)
2658 var sFsmName = "OnuSwUpgradeFSM"
2659 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002660 if apDevEntry.PDevOmciCC == nil {
2661 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2662 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002663 }
mpagenko15ff4a52021-03-02 10:09:20 +00002664 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002665 sFsmName, chUpgradeFsm)
2666 if dh.pOnuUpradeFsm != nil {
2667 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2668 if pUpgradeStatemachine != nil {
2669 if pUpgradeStatemachine.Is(upgradeStDisabled) {
mpagenkoaa3afe92021-05-21 16:20:58 +00002670 dh.upgradeSuccess = false //for start of upgrade processing reset the last indication
mpagenko80622a52021-02-09 16:53:23 +00002671 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2672 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2673 // maybe try a FSM reset and then again ... - TODO!!!
2674 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2675 }
2676 /***** LockStateFSM started */
2677 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2678 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2679 } else {
2680 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2681 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2682 // maybe try a FSM reset and then again ... - TODO!!!
2683 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2684 }
2685 } else {
2686 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2687 // maybe try a FSM reset and then again ... - TODO!!!
2688 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2689 }
2690 } else {
2691 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2692 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2693 }
2694 return nil
2695}
2696
2697// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2698func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2699 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2700 "device-id": dh.deviceID})
2701 dh.lockUpgradeFsm.Lock()
2702 defer dh.lockUpgradeFsm.Unlock()
2703 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2704}
2705
mpagenko15ff4a52021-03-02 10:09:20 +00002706// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2707func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2708 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2709 if pDevEntry == nil {
2710 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2711 return
2712 }
2713
2714 dh.lockUpgradeFsm.RLock()
2715 defer dh.lockUpgradeFsm.RUnlock()
2716 if dh.pOnuUpradeFsm != nil {
2717 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2718 if pUpgradeStatemachine != nil {
2719 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2720 // (some manual forced commit could do without)
mpagenko1f8e8822021-06-25 14:10:21 +00002721 upgradeState := pUpgradeStatemachine.Current()
2722 if (upgradeState == upgradeStWaitForCommit) ||
2723 (upgradeState == upgradeStRequestingActivate) {
2724 // also include upgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00002725 // 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 +00002726 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00002727 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
2728 if errImg != nil {
2729 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
2730 log.Fields{"device-id": dh.deviceID})
2731 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
mpagenko15ff4a52021-03-02 10:09:20 +00002732 return
2733 }
mpagenko1f8e8822021-06-25 14:10:21 +00002734 if activeImageID == dh.pOnuUpradeFsm.inactiveImageMeID {
2735 if (upgradeState == upgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
2736 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
2737 if err := pUpgradeStatemachine.Event(upgradeEvActivationDone); err != nil {
2738 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
2739 return
2740 }
2741 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
2742 "state": upgradeState, "device-id": dh.deviceID})
2743 } else {
2744 //FSM in waitForCommit or (upgradeStRequestingActivate [lost ActivateResp] and commit allowed)
2745 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2746 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2747 return
2748 }
2749 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2750 "state": upgradeState, "device-id": dh.deviceID})
2751 }
2752 } else {
2753 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit/on ActivateResponse, but load did not start with expected image Id",
2754 log.Fields{"device-id": dh.deviceID})
2755 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2756 return
2757 }
mpagenko15ff4a52021-03-02 10:09:20 +00002758 } else {
2759 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2760 log.Fields{"device-id": dh.deviceID})
2761 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2762 return
2763 }
mpagenko183647c2021-06-08 15:25:04 +00002764 } else {
2765 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2766 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2767 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2768 if dh.pOnuUpradeFsm.inactiveImageMeID == activeImageID {
2769 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2770 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2771 dh.pOnuUpradeFsm.SetImageState(ctx, voltha.ImageState_IMAGE_ACTIVE)
2772 }
2773 }
mpagenko15ff4a52021-03-02 10:09:20 +00002774 }
2775 }
2776 } else {
2777 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2778 }
2779}
2780
Himani Chawla6d2ae152020-09-02 13:11:20 +05302781//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002782func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002783
2784 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002785 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07002786 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00002787 kvbackend := &db.Backend{
2788 Client: dh.pOpenOnuAc.kvClient,
2789 StoreType: dh.pOpenOnuAc.KVStoreType,
2790 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002791 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002792 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2793 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002794
mpagenkoaf801632020-07-03 10:00:42 +00002795 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002796}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002797func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302798 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002799
mpagenkodff5dda2020-08-28 11:52:01 +00002800 for _, field := range flow.GetOfbFields(apFlowItem) {
2801 switch field.Type {
2802 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2803 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002804 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002805 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2806 }
mpagenko01e726e2020-10-23 09:45:29 +00002807 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002808 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2809 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302810 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002811 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302812 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2813 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002814 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2815 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002816 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2817 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302818 return
mpagenkodff5dda2020-08-28 11:52:01 +00002819 }
2820 }
mpagenko01e726e2020-10-23 09:45:29 +00002821 */
mpagenkodff5dda2020-08-28 11:52:01 +00002822 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2823 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302824 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002825 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302826 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002827 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302828 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002829 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002830 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302831 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002832 }
2833 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2834 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302835 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002836 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002837 "PCP": loAddPcp})
2838 }
2839 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2840 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002841 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002842 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2843 }
2844 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2845 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002846 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002847 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2848 }
2849 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2850 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002851 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002852 "IPv4-DST": field.GetIpv4Dst()})
2853 }
2854 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2855 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002856 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002857 "IPv4-SRC": field.GetIpv4Src()})
2858 }
2859 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2860 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002861 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002862 "Metadata": field.GetTableMetadata()})
2863 }
2864 /*
2865 default:
2866 {
2867 //all other entires ignored
2868 }
2869 */
2870 }
2871 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302872}
mpagenkodff5dda2020-08-28 11:52:01 +00002873
dbainbri4d3a0dc2020-12-02 00:33:42 +00002874func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002875 for _, action := range flow.GetActions(apFlowItem) {
2876 switch action.Type {
2877 /* not used:
2878 case of.OfpActionType_OFPAT_OUTPUT:
2879 {
mpagenko01e726e2020-10-23 09:45:29 +00002880 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002881 "Output": action.GetOutput()})
2882 }
2883 */
2884 case of.OfpActionType_OFPAT_PUSH_VLAN:
2885 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002886 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002887 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2888 }
2889 case of.OfpActionType_OFPAT_SET_FIELD:
2890 {
2891 pActionSetField := action.GetSetField()
2892 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002893 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002894 "OxcmClass": pActionSetField.Field.OxmClass})
2895 }
2896 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302897 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002898 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302899 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002900 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302901 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002902 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302903 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002904 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002905 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002906 "Type": pActionSetField.Field.GetOfbField().Type})
2907 }
2908 }
2909 /*
2910 default:
2911 {
2912 //all other entires ignored
2913 }
2914 */
2915 }
2916 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302917}
2918
2919//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
ozgecanetsia82b91a62021-05-21 18:54:49 +03002920func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort,
2921 apFlowMetaData *voltha.FlowMetadata) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302922 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2923 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2924 var loAddPcp, loSetPcp uint8
2925 var loIPProto uint32
2926 /* the TechProfileId is part of the flow Metadata - compare also comment within
2927 * OLT-Adapter:openolt_flowmgr.go
2928 * Metadata 8 bytes:
2929 * Most Significant 2 Bytes = Inner VLAN
2930 * Next 2 Bytes = Tech Profile ID(TPID)
2931 * Least Significant 4 Bytes = Port ID
2932 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2933 * subscriber related flows.
2934 */
2935
dbainbri4d3a0dc2020-12-02 00:33:42 +00002936 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302937 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002938 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302939 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002940 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302941 }
mpagenko551a4d42020-12-08 18:09:20 +00002942 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002943 loCookie := apFlowItem.GetCookie()
2944 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002945 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002946 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302947
dbainbri4d3a0dc2020-12-02 00:33:42 +00002948 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002949 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302950 if loIPProto == 2 {
2951 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2952 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002953 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2954 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302955 return nil
2956 }
mpagenko01e726e2020-10-23 09:45:29 +00002957 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002958 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002959
2960 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002961 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002962 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2963 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2964 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2965 //TODO!!: Use DeviceId within the error response to rwCore
2966 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002967 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002968 }
2969 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002970 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002971 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2972 } else {
2973 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2974 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2975 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302976 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002977 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002978 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002979 }
mpagenko9a304ea2020-12-16 15:54:01 +00002980
2981 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenko7d14de12021-07-27 08:31:56 +00002982 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
2983 // when different rules are requested concurrently for the same uni
2984 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
2985 dh.lockVlanConfig.Lock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03002986 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID, "tpID": loTpID, "uniID": apUniPort.uniID})
2987 var meter *voltha.OfpMeterConfig
2988 if apFlowMetaData != nil {
2989 meter = apFlowMetaData.Meters[0]
2990 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302991 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002992 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03002993 loMatchVlan, loSetVlan, loSetPcp, false, meter)
mpagenko7d14de12021-07-27 08:31:56 +00002994 dh.lockVlanConfig.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +00002995 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002996 }
mpagenko7d14de12021-07-27 08:31:56 +00002997 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03002998 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false, meter)
mpagenko7d14de12021-07-27 08:31:56 +00002999 dh.lockVlanConfig.Unlock()
3000 return err
mpagenko01e726e2020-10-23 09:45:29 +00003001}
3002
3003//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00003004func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00003005 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3006 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3007 //no extra check is done on the rule parameters
3008 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3009 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3010 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3011 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003012 // - 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 +00003013 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003014 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003015
3016 /* TT related temporary workaround - should not be needed anymore
3017 for _, field := range flow.GetOfbFields(apFlowItem) {
3018 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3019 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00003020 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003021 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3022 if loIPProto == 2 {
3023 // 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 +00003024 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00003025 log.Fields{"device-id": dh.deviceID})
3026 return nil
3027 }
3028 }
3029 } //for all OfbFields
3030 */
3031
mpagenko9a304ea2020-12-16 15:54:01 +00003032 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003033 dh.lockVlanConfig.RLock()
3034 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00003035 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003036 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00003037 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003038 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00003039 log.Fields{"device-id": dh.deviceID})
3040 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003041 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00003042 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00003043
mpagenko01e726e2020-10-23 09:45:29 +00003044 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00003045}
3046
Himani Chawla26e555c2020-08-31 12:30:20 +05303047// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003048// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003049// precondition: dh.lockVlanConfig is locked by the caller!
mpagenko551a4d42020-12-08 18:09:20 +00003050func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003051 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
mpagenkodff5dda2020-08-28 11:52:01 +00003052 chVlanFilterFsm := make(chan Message, 2048)
3053
dbainbri4d3a0dc2020-12-02 00:33:42 +00003054 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003055 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003056 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303057 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003058 }
3059
dbainbri4d3a0dc2020-12-02 00:33:42 +00003060 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00003061 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003062 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter)
mpagenkodff5dda2020-08-28 11:52:01 +00003063 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003064 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3065 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Himani Chawla26e555c2020-08-31 12:30:20 +05303066 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003067 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3068 if pVlanFilterStatemachine != nil {
3069 if pVlanFilterStatemachine.Is(vlanStDisabled) {
3070 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003071 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05303072 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003073 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303074 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003075 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05303076 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3077 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003078 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003079 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003080 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303081 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003082 }
3083 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003084 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003085 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303086 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003087 }
3088 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003089 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003090 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05303091 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003092 }
3093 return nil
3094}
3095
mpagenkofc4f56e2020-11-04 17:17:49 +00003096//VerifyVlanConfigRequest checks on existence of a given uniPort
3097// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003098func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003099 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
3100 var pCurrentUniPort *onuUniPort
3101 for _, uniPort := range dh.uniEntityMap {
3102 // only if this port is validated for operState transfer
3103 if uniPort.uniID == uint8(aUniID) {
3104 pCurrentUniPort = uniPort
3105 break //found - end search loop
3106 }
3107 }
3108 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003109 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00003110 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
3111 return
3112 }
mpagenko551a4d42020-12-08 18:09:20 +00003113 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003114}
3115
mpagenkodff5dda2020-08-28 11:52:01 +00003116//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00003117func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003118 //TODO!! verify and start pending flow configuration
3119 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3120 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003121
3122 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303123 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003124 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003125 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
3126 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3127 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003128 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
3129 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
3130 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
3131 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
3132 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3133 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3134 } else {
3135 /***** UniVlanConfigFsm continued */
3136 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
3137 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3138 "UniPort": apUniPort.portNo})
3139 }
3140 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
3141 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
3142 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3143 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3144 } else {
3145 /***** UniVlanConfigFsm continued */
3146 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3147 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3148 "UniPort": apUniPort.portNo})
3149 }
mpagenkodff5dda2020-08-28 11:52:01 +00003150 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003151 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3152 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003153 "UniPort": apUniPort.portNo})
3154 }
3155 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003156 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3157 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3158 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003159 }
3160 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003161 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003162 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003163 }
mpagenkof1fc3862021-02-16 10:09:52 +00003164 } else {
3165 dh.lockVlanConfig.RUnlock()
3166 }
mpagenkodff5dda2020-08-28 11:52:01 +00003167}
3168
3169//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3170// 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 +00003171func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3172 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003173 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3174 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003175 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303176 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003177 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003178}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003179
mpagenkof1fc3862021-02-16 10:09:52 +00003180//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3181func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3182 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3183 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3184 // obviously then parallel processing on the cancel must be avoided
3185 // deadline context to ensure completion of background routines waited for
3186 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3187 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3188 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3189
3190 aPDevEntry.resetKvProcessingErrorIndication()
3191 var wg sync.WaitGroup
3192 wg.Add(1) // for the 1 go routine to finish
3193
3194 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3195 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3196
3197 return aPDevEntry.getKvProcessingErrorIndication()
3198}
3199
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003200//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3201//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003202func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3203 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003204
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003205 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003206 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003207 return nil
3208 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003209 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003210
dbainbri4d3a0dc2020-12-02 00:33:42 +00003211 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003212 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003213 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003214 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3215 }
3216 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3217
mpagenkof1fc3862021-02-16 10:09:52 +00003218 if aWriteToKvStore {
3219 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3220 }
3221 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003222}
3223
dbainbri4d3a0dc2020-12-02 00:33:42 +00003224func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003225 defer cancel() //ensure termination of context (may be pro forma)
3226 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003227 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003228 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003229}
3230
dbainbri4d3a0dc2020-12-02 00:33:42 +00003231func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003232
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003233 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003234 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003235 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003236 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3237 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003238 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003239 return err
3240 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003241 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003242 return nil
3243 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003244 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003245 return nil
3246}
3247
dbainbri4d3a0dc2020-12-02 00:33:42 +00003248func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3249 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003250 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003251 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003252 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3253 }
mpagenkof1fc3862021-02-16 10:09:52 +00003254 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003255}
3256
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003257func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
3258 var errStr string = ""
3259 for _, err := range errS {
3260 if err != nil {
3261 errStr = errStr + err.Error() + " "
3262 }
3263 }
3264 if errStr != "" {
3265 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
3266 }
3267 return nil
3268}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003269
3270// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003271// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003272func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3273 dh.lockDevice.RLock()
3274 defer dh.lockDevice.RUnlock()
3275 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3276 return uniPort.entityID, nil
3277 }
3278 return 0, errors.New("error-fetching-uni-port")
3279}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003280
3281// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003282func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3283 var errorsList []error
3284 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 -08003285
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003286 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3287 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3288 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3289
3290 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3291 // successfully.
3292 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3293 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3294 if len(errorsList) > 0 {
3295 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3296 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003297 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003298 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3299 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003300}
3301
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003302func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3303 var err error
3304 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003305 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003306
3307 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3308 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3309 errorsList = append(errorsList, err)
3310 }
3311 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003312 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003313
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003314 return errorsList
3315}
3316
3317func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3318 var err error
3319 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003320 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003321 // Check if group metric related config is updated
3322 for _, v := range pmConfigs.Groups {
3323 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3324 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3325 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3326
3327 if ok && m.frequency != v.GroupFreq {
3328 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3329 errorsList = append(errorsList, err)
3330 }
3331 }
3332 if ok && m.enabled != v.Enabled {
3333 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3334 errorsList = append(errorsList, err)
3335 }
3336 }
3337 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003338 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003339 return errorsList
3340}
3341
3342func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3343 var err error
3344 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003345 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003346 // Check if standalone metric related config is updated
3347 for _, v := range pmConfigs.Metrics {
3348 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003349 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003350 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3351
3352 if ok && m.frequency != v.SampleFreq {
3353 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3354 errorsList = append(errorsList, err)
3355 }
3356 }
3357 if ok && m.enabled != v.Enabled {
3358 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3359 errorsList = append(errorsList, err)
3360 }
3361 }
3362 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003363 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003364 return errorsList
3365}
3366
3367// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003368func (dh *deviceHandler) startCollector(ctx context.Context) {
3369 logger.Debugf(ctx, "startingCollector")
3370
3371 // Start routine to process OMCI GET Responses
3372 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303373 // Create Extended Frame PM ME
3374 go dh.pOnuMetricsMgr.createEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003375 // Initialize the next metric collection time.
3376 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3377 // reset like onu rebooted.
3378 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003379 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003380 for {
3381 select {
3382 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003383 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003384 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003385 // Stop the L2 PM FSM
3386 go func() {
3387 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3388 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3389 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3390 }
3391 } else {
3392 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3393 }
3394 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003395 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3396 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3397 }
3398 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3399 dh.pOnuMetricsMgr.stopTicks <- true
3400 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003401
Girish Gowdrae09a6202021-01-12 18:10:59 -08003402 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003403 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3404 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3405 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3406 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3407 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003408 // Update the next metric collection time.
3409 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003410 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003411 } else {
3412 if dh.pmConfigs.Grouped { // metrics are managed as a group
3413 // parse through the group and standalone metrics to see it is time to collect their metrics
3414 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003415
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003416 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3417 // 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 -08003418 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3419 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003420 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3421 }
3422 }
3423 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3424 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3425 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3426 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3427 }
3428 }
3429 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3430
3431 // parse through the group and update the next metric collection time
3432 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3433 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3434 // 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 -08003435 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3436 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003437 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3438 }
3439 }
3440 // parse through the standalone metrics and update the next metric collection time
3441 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3442 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3443 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3444 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3445 }
3446 }
3447 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3448 } /* else { // metrics are not managed as a group
3449 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3450 } */
3451 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003452 }
3453 }
3454}
kesavandfdf77632021-01-26 23:40:33 -05003455
3456func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3457
3458 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3459 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3460}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003461
Himani Chawla43f95ff2021-06-03 00:24:12 +05303462func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3463 if dh.pOnuMetricsMgr == nil {
3464 return &extension.SingleGetValueResponse{
3465 Response: &extension.GetValueResponse{
3466 Status: extension.GetValueResponse_ERROR,
3467 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3468 },
3469 }
3470 }
3471 resp := dh.pOnuMetricsMgr.collectEthernetFrameExtendedPMCounters(ctx)
3472 return resp
3473}
3474
mpagenkof1fc3862021-02-16 10:09:52 +00003475func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3476 if pFsm == nil {
3477 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003478 }
mpagenkof1fc3862021-02-16 10:09:52 +00003479 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003480}
3481
mpagenkof1fc3862021-02-16 10:09:52 +00003482func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3483 var pFsm *fsm.FSM
3484 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3485 switch omciFsm {
3486 case cUploadFsm:
3487 {
3488 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3489 }
3490 case cDownloadFsm:
3491 {
3492 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3493 }
3494 case cUniLockFsm:
3495 {
3496 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3497 }
3498 case cUniUnLockFsm:
3499 {
3500 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3501 }
3502 case cL2PmFsm:
3503 {
3504 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3505 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3506 } else {
3507 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003508 }
3509 }
mpagenko80622a52021-02-09 16:53:23 +00003510 case cOnuUpgradeFsm:
3511 {
3512 dh.lockUpgradeFsm.RLock()
3513 defer dh.lockUpgradeFsm.RUnlock()
3514 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3515 }
mpagenkof1fc3862021-02-16 10:09:52 +00003516 default:
3517 {
3518 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3519 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3520 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003521 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003522 }
mpagenkof1fc3862021-02-16 10:09:52 +00003523 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003524}
3525
mpagenkof1fc3862021-02-16 10:09:52 +00003526func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3527 for _, v := range dh.pOnuTP.pAniConfigFsm {
3528 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003529 return false
3530 }
3531 }
3532 return true
3533}
3534
mpagenkof1fc3862021-02-16 10:09:52 +00003535func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3536 dh.lockVlanConfig.RLock()
3537 defer dh.lockVlanConfig.RUnlock()
3538 for _, v := range dh.UniVlanConfigFsmMap {
3539 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3540 return false
3541 }
3542 }
3543 return true //FSM not active - so there is no activity on omci
3544}
3545
3546func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3547 dh.lockVlanConfig.RLock()
3548 defer dh.lockVlanConfig.RUnlock()
3549 for _, v := range dh.UniVlanConfigFsmMap {
3550 if v.pAdaptFsm.pFsm != nil {
3551 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3552 return true //there is at least one VLAN FSM with some active configuration
3553 }
3554 }
3555 }
3556 return false //there is no VLAN FSM with some active configuration
3557}
3558
3559func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3560 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3561 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3562 return false
3563 }
3564 }
3565 // a further check is done to identify, if at least some data traffic related configuration exists
3566 // 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])
3567 return dh.checkUserServiceExists(ctx)
3568}
3569
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003570func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3571 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3572 if err := dh.resetFsms(ctx, false); err != nil {
3573 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3574 // TODO: fatal error reset ONU, delete deviceHandler!
3575 return
3576 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003577 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003578 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003579}
3580
3581func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3582 dh.mutexCollectorFlag.Lock()
3583 dh.collectorIsRunning = flagValue
3584 dh.mutexCollectorFlag.Unlock()
3585}
3586
3587func (dh *deviceHandler) getCollectorIsRunning() bool {
3588 dh.mutexCollectorFlag.RLock()
3589 flagValue := dh.collectorIsRunning
3590 dh.mutexCollectorFlag.RUnlock()
3591 return flagValue
3592}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303593
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303594func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3595 dh.mutextAlarmManagerFlag.Lock()
3596 dh.alarmManagerIsRunning = flagValue
3597 dh.mutextAlarmManagerFlag.Unlock()
3598}
3599
Himani Chawla1472c682021-03-17 17:11:14 +05303600func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303601 dh.mutextAlarmManagerFlag.RLock()
3602 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303603 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303604 dh.mutextAlarmManagerFlag.RUnlock()
3605 return flagValue
3606}
3607
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303608func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3609 logger.Debugf(ctx, "startingAlarmManager")
3610
3611 // Start routine to process OMCI GET Responses
3612 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303613 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303614 if stop := <-dh.stopAlarmManager; stop {
3615 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303616 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303617 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303618 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3619 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3620 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303621 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303622 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303623 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3624 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303625 }
3626}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003627
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003628func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003629 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003630
Maninder7961d722021-06-16 22:10:28 +05303631 connectStatus := voltha.ConnectStatus_UNREACHABLE
3632 operState := voltha.OperStatus_UNKNOWN
3633
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003634 if !dh.isReconciling() {
3635 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003636 logger.Debugw(ctx, "wait for channel signal or timeout",
3637 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003638 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003639 case success := <-dh.chReconcilingFinished:
3640 if success {
Maninderb5187552021-03-23 22:23:42 +05303641 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3642 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3643 log.Fields{"device-id": dh.deviceID})
3644 } else {
Maninderb5187552021-03-23 22:23:42 +05303645 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3646 connectStatus = voltha.ConnectStatus_REACHABLE
3647 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3648 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3649 operState = voltha.OperStatus_ACTIVE
3650 } else {
3651 operState = voltha.OperStatus_ACTIVATING
3652 }
3653 }
3654 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3655 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3656 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3657 operState = voltha.OperStatus_DISCOVERED
3658 }
3659
3660 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303661 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003662 logger.Debugw(ctx, "reconciling has been finished in time",
3663 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303664 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, operState); err != nil {
3665 logger.Errorw(ctx, "unable to update device state to core",
3666 log.Fields{"device-id": dh.deviceID, "Err": err})
3667 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003668 } else {
Maninderb5187552021-03-23 22:23:42 +05303669 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003670 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303671
3672 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3673 logger.Errorw(ctx, "No valid OnuDevice",
3674 log.Fields{"device-id": dh.deviceID})
3675 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3676 connectStatus = voltha.ConnectStatus_REACHABLE
3677 }
3678
3679 dh.deviceReconcileFailedUpdate(ctx, drReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003680 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003681 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003682 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3683 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303684
3685 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3686 logger.Errorw(ctx, "No valid OnuDevice",
3687 log.Fields{"device-id": dh.deviceID})
3688 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3689 connectStatus = voltha.ConnectStatus_REACHABLE
3690 }
3691
3692 dh.deviceReconcileFailedUpdate(ctx, drReconcileMaxTimeout, connectStatus)
3693
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003694 }
3695 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003696 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003697 dh.mutexReconcilingFlag.Unlock()
3698 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003699 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003700 dh.mutexReconcilingFlag.Lock()
3701 if skipOnuConfig {
3702 dh.reconciling = cSkipOnuConfigReconciling
3703 } else {
3704 dh.reconciling = cOnuConfigReconciling
3705 }
3706 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003707}
3708
Girish Gowdra50e56422021-06-01 16:46:04 -07003709func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool) {
3710 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID, "success": success})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003711 if dh.isReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07003712 dh.chReconcilingFinished <- success
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003713 } else {
3714 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3715 }
3716}
3717
3718func (dh *deviceHandler) isReconciling() bool {
3719 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003720 defer dh.mutexReconcilingFlag.RUnlock()
3721 return dh.reconciling != cNoReconciling
3722}
3723
3724func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3725 dh.mutexReconcilingFlag.RLock()
3726 defer dh.mutexReconcilingFlag.RUnlock()
3727 return dh.reconciling == cSkipOnuConfigReconciling
3728}
3729
3730func (dh *deviceHandler) setDeviceReason(value uint8) {
3731 dh.mutexDeviceReason.Lock()
3732 dh.deviceReason = value
3733 dh.mutexDeviceReason.Unlock()
3734}
3735
3736func (dh *deviceHandler) getDeviceReason() uint8 {
3737 dh.mutexDeviceReason.RLock()
3738 value := dh.deviceReason
3739 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003740 return value
3741}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003742
3743func (dh *deviceHandler) getDeviceReasonString() string {
3744 return deviceReasonMap[dh.getDeviceReason()]
3745}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003746
3747func (dh *deviceHandler) setReconcilingFlows(value bool) {
3748 dh.mutexReconcilingFlowsFlag.Lock()
3749 dh.reconcilingFlows = value
3750 dh.mutexReconcilingFlowsFlag.Unlock()
3751}
3752
3753func (dh *deviceHandler) isReconcilingFlows() bool {
3754 dh.mutexReconcilingFlowsFlag.RLock()
3755 value := dh.reconcilingFlows
3756 dh.mutexReconcilingFlowsFlag.RUnlock()
3757 return value
3758}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003759
3760func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3761 dh.mutexReadyForOmciConfig.Lock()
3762 dh.readyForOmciConfig = flagValue
3763 dh.mutexReadyForOmciConfig.Unlock()
3764}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003765func (dh *deviceHandler) isReadyForOmciConfig() bool {
3766 dh.mutexReadyForOmciConfig.RLock()
3767 flagValue := dh.readyForOmciConfig
3768 dh.mutexReadyForOmciConfig.RUnlock()
3769 return flagValue
3770}
Maninder7961d722021-06-16 22:10:28 +05303771
3772func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
3773 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
3774 logger.Errorw(ctx, "unable to update device reason to core",
3775 log.Fields{"device-id": dh.deviceID, "Err": err})
3776 }
3777
3778 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
3779 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, voltha.OperStatus_RECONCILING_FAILED); err != nil {
3780 logger.Errorw(ctx, "unable to update device state to core",
3781 log.Fields{"device-id": dh.deviceID, "Err": err})
3782 }
3783}