blob: 65051f6c2954717e50bc89e8bc7c6bd229ef4744 [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
mpagenkof1fc3862021-02-16 10:09:52 +00001011 dh.lockVlanConfig.RLock()
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 }
mpagenkof1fc3862021-02-16 10:09:52 +00001018 dh.lockVlanConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001019 } else {
mpagenkof1fc3862021-02-16 10:09:52 +00001020 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001021 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00001022 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +03001023 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001024 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001025 }
1026 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001027 flowsProcessed++
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001028 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001029 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{"device-id": dh.deviceID, "flowsProcessed": flowsProcessed,
1030 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
1031 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001032 // this can't be used as global finished reconciling flag because
1033 // assumes is getting called before the state machines for the last flow is completed,
1034 // while this is not guaranteed.
1035 //dh.setReconcilingFlows(false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001036 }
1037 if !flowsFound {
1038 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
1039 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001040 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001041 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001042 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001043 return
1044 }
1045 if dh.isSkipOnuConfigReconciling() {
1046 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001047 }
1048}
1049
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001050func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
1051 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001052 dh.stopReconciling(ctx, true)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001053}
1054
dbainbri4d3a0dc2020-12-02 00:33:42 +00001055func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
1056 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001057
dbainbri4d3a0dc2020-12-02 00:33:42 +00001058 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001059 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001060 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +00001061 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001062 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001063 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001064
1065 // deadline context to ensure completion of background routines waited for
1066 //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 +05301067 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001068 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001069
1070 pDevEntry.resetKvProcessingErrorIndication()
1071
1072 var wg sync.WaitGroup
1073 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001074 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1075 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001076
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001077 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001078 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001079}
1080
mpagenko15ff4a52021-03-02 10:09:20 +00001081//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1082// before this change here return like this was used:
1083// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1084//was and is called in background - error return does not make sense
1085func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1086 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1087 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001088 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001089 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001090 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001091 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301092 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001093 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001094 return
Himani Chawla4d908332020-08-31 12:30:20 +05301095 }
mpagenko01e726e2020-10-23 09:45:29 +00001096
1097 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001098 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001099
dbainbri4d3a0dc2020-12-02 00:33:42 +00001100 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001101 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001102 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001103 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001104 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001105 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001106 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001107 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001108 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001109 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001110 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001111 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001112 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1113 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1114 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1115 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001116}
1117
mpagenkoc8bba412021-01-15 15:38:44 +00001118//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +00001119func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1120 apDownloadManager *adapterDownloadManager) error {
1121 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001122 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001123
1124 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001125 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1126 if pDevEntry == nil {
1127 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1128 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1129 }
1130
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001131 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001132 var inactiveImageID uint16
1133 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1134 dh.lockUpgradeFsm.Lock()
1135 defer dh.lockUpgradeFsm.Unlock()
1136 if dh.pOnuUpradeFsm == nil {
1137 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1138 if err == nil {
1139 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1140 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1141 "device-id": dh.deviceID, "error": err})
1142 }
1143 } else {
1144 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001145 "device-id": dh.deviceID, "error": err})
1146 }
mpagenko15ff4a52021-03-02 10:09:20 +00001147 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1148 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1149 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1150 if pUpgradeStatemachine != nil {
1151 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1152 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1153 "device-id": dh.deviceID, "error": err})
1154 }
1155 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1156 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1157 // for now a second start of download should work again
1158 } else { //should never occur
1159 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1160 "device-id": dh.deviceID})
1161 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001162 }
mpagenko80622a52021-02-09 16:53:23 +00001163 }
mpagenko15ff4a52021-03-02 10:09:20 +00001164 } else {
1165 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1166 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001167 }
1168 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001169 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1170 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001171 }
1172 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001173}
1174
mpagenkoc26d4c02021-05-06 14:27:57 +00001175//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1176// after the OnuImage has been downloaded to the adapter, called in background
1177func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
1178 apDownloadManager *fileDownloadManager, aImageIdentifier string) {
1179
1180 var err error
1181 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1182 if pDevEntry == nil {
1183 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1184 return
1185 }
1186
1187 var inactiveImageID uint16
1188 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1189 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
1190 "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
1191 dh.lockUpgradeFsm.Lock()
1192 defer dh.lockUpgradeFsm.Unlock()
1193 if dh.pOnuUpradeFsm == nil {
1194 //OmciOnuSwUpgradeDone could be used to create some Kafka event with information on upgrade completion,
1195 // but none yet defined
1196 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1197 if err == nil {
1198 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
Holger Hildebrandtac010732021-06-02 13:35:39 +00001199 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00001200 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1201 "device-id": dh.deviceID, "error": err})
1202 return
1203 }
1204 } else {
1205 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1206 "device-id": dh.deviceID, "error": err})
1207 }
1208 return
1209 }
1210 //OnuSw upgrade already running - restart (with possible abort of running)
1211 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1212 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1213 if pUpgradeStatemachine != nil {
1214 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1215 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1216 "device-id": dh.deviceID, "error": err})
1217 return
1218 }
1219 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1220 // for now a second start of download should work again - must still be initiated by user
1221 } else { //should never occur
1222 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1223 "device-id": dh.deviceID})
1224 }
1225 return
1226 }
1227 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1228 "device-id": dh.deviceID, "error": err})
1229}
1230
1231//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001232func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1233 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001234 var err error
1235 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1236 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1237 // 2.) activation of the inactive image
1238
1239 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1240 if pDevEntry == nil {
1241 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001242 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001243 }
1244 dh.lockUpgradeFsm.RLock()
1245 if dh.pOnuUpradeFsm != nil {
1246 dh.lockUpgradeFsm.RUnlock()
1247 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1248 dh.deviceID, dh.deviceID)
1249 if getErr != nil || onuVolthaDevice == nil {
1250 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 +00001251 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001252 }
1253 // use the OnuVendor identification from this device for the internal unique name
1254 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1255 // 1.) check a started upgrade process and rely the activation request to it
1256 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001257 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001258 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1259 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001260 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001261 }
mpagenko183647c2021-06-08 15:25:04 +00001262 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1263 "device-id": dh.deviceID, "image-id": imageIdentifier})
1264 var pImageStates *voltha.ImageState
1265 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1266 pImageStates = &voltha.ImageState{}
1267 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1268 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1269 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1270 }
1271 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001272 } //else
1273 dh.lockUpgradeFsm.RUnlock()
1274
1275 // 2.) check if requested image-version equals the inactive one and start its activation
1276 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1277 var inactiveImageID uint16
1278 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1279 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1280 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
mpagenko183647c2021-06-08 15:25:04 +00001281 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001282 }
1283 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1284 if err == nil {
1285 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1286 inactiveImageID, aCommitRequest); err != nil {
1287 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1288 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001289 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001290 }
1291 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1292 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001293 var pImageStates *voltha.ImageState
1294 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1295 pImageStates := &voltha.ImageState{}
1296 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1297 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1298 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1299 }
1300 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001301 } //else
1302 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1303 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001304 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001305}
1306
1307//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001308func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1309 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001310 var err error
1311 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1312 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1313 // 2.) commitment of the active image
1314
1315 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1316 if pDevEntry == nil {
1317 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001318 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001319 }
1320 dh.lockUpgradeFsm.RLock()
1321 if dh.pOnuUpradeFsm != nil {
1322 dh.lockUpgradeFsm.RUnlock()
1323 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1324 dh.deviceID, dh.deviceID)
1325 if getErr != nil || onuVolthaDevice == nil {
1326 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 +00001327 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001328 }
1329 // use the OnuVendor identification from this device for the internal unique name
1330 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1331 // 1.) check a started upgrade process and rely the commitment request to it
1332 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001333 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001334 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1335 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001336 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001337 }
mpagenko183647c2021-06-08 15:25:04 +00001338 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1339 "device-id": dh.deviceID, "image-id": imageIdentifier})
1340 var pImageStates *voltha.ImageState
1341 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1342 pImageStates := &voltha.ImageState{}
1343 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1344 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1345 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1346 }
1347 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001348 } //else
1349 dh.lockUpgradeFsm.RUnlock()
1350
mpagenko183647c2021-06-08 15:25:04 +00001351 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001352 var activeImageID uint16
1353 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1354 logger.Errorw(ctx, "get active image failed", log.Fields{
1355 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
mpagenko183647c2021-06-08 15:25:04 +00001356 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001357 }
1358 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1359 if err == nil {
1360 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1361 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1362 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001363 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001364 }
1365 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1366 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001367 var pImageStates *voltha.ImageState
1368 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1369 pImageStates := &voltha.ImageState{}
1370 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1371 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1372 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1373 }
1374 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001375 } //else
1376 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1377 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001378 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001379}
1380
mpagenkoaa3afe92021-05-21 16:20:58 +00001381func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
1382 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1383 pDeviceImageState.DeviceId = dh.deviceID
mpagenko183647c2021-06-08 15:25:04 +00001384 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001385 dh.lockUpgradeFsm.RLock()
1386 if dh.pOnuUpradeFsm != nil {
1387 dh.lockUpgradeFsm.RUnlock()
mpagenko183647c2021-06-08 15:25:04 +00001388 if pImageStates, err := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion); err == nil {
mpagenkoaa3afe92021-05-21 16:20:58 +00001389 pDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
1390 pDeviceImageState.ImageState.Reason = pImageStates.Reason
1391 pDeviceImageState.ImageState.ImageState = pImageStates.ImageState
1392 } else {
1393 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1394 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1395 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1396 }
1397 } else {
1398 dh.lockUpgradeFsm.RUnlock()
1399 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1400 if dh.upgradeSuccess {
1401 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
1402 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMITTED
1403 } else {
1404 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1405 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1406 }
1407 }
1408}
1409
1410func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1411 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1412 pDeviceImageState.DeviceId = dh.deviceID
mpagenko7455fd42021-06-10 16:25:55 +00001413 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001414 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1415 dh.lockUpgradeFsm.RLock()
1416 if dh.pOnuUpradeFsm != nil {
1417 dh.lockUpgradeFsm.RUnlock()
1418 //option: it could be also checked if the upgrade FSM is running on the given imageIdentifier or version
1419 // by now just straightforward assume this to be true
1420 dh.pOnuUpradeFsm.CancelProcessing(ctx)
1421 //nolint:misspell
1422 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
1423 //nolint:misspell
1424 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1425 } else {
1426 dh.lockUpgradeFsm.RUnlock()
1427 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1428 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1429 }
1430}
1431
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001432func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1433
1434 var onuImageStatus *OnuImageStatus
1435
1436 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1437 if pDevEntry != nil {
1438 onuImageStatus = NewOnuImageStatus(pDevEntry)
1439 pDevEntry.mutexOnuImageStatus.Lock()
1440 pDevEntry.pOnuImageStatus = onuImageStatus
1441 pDevEntry.mutexOnuImageStatus.Unlock()
1442
1443 } else {
1444 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1445 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1446 }
1447 images, err := onuImageStatus.getOnuImageStatus(ctx)
1448 pDevEntry.mutexOnuImageStatus.Lock()
1449 pDevEntry.pOnuImageStatus = nil
1450 pDevEntry.mutexOnuImageStatus.Unlock()
1451 return images, err
1452}
1453
Himani Chawla6d2ae152020-09-02 13:11:20 +05301454// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001455// #####################################################################################
1456
1457// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301458// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001459
dbainbri4d3a0dc2020-12-02 00:33:42 +00001460func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1461 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 +00001462}
1463
1464// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001465func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001466
dbainbri4d3a0dc2020-12-02 00:33:42 +00001467 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001468 var err error
1469
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001470 // populate what we know. rest comes later after mib sync
1471 dh.device.Root = false
1472 dh.device.Vendor = "OpenONU"
1473 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001474 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001475 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001476
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001477 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001478
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001479 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001480 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1481 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301482 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001483 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001484 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001485 log.Fields{"device-id": dh.deviceID})
1486 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001487
Himani Chawla4d908332020-08-31 12:30:20 +05301488 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001489 dh.ponPortNumber = dh.device.ParentPortNo
1490
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001491 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1492 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1493 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001494 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001495 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301496 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001497
1498 /*
1499 self._pon = PonPort.create(self, self._pon_port_number)
1500 self._pon.add_peer(self.parent_id, self._pon_port_number)
1501 self.logger.debug('adding-pon-port-to-agent',
1502 type=self._pon.get_port().type,
1503 admin_state=self._pon.get_port().admin_state,
1504 oper_status=self._pon.get_port().oper_status,
1505 )
1506 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001507 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001508 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001509 var ponPortNo uint32 = 1
1510 if dh.ponPortNumber != 0 {
1511 ponPortNo = dh.ponPortNumber
1512 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001513
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001514 pPonPort := &voltha.Port{
1515 PortNo: ponPortNo,
1516 Label: fmt.Sprintf("pon-%d", ponPortNo),
1517 Type: voltha.Port_PON_ONU,
1518 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301519 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001520 PortNo: ponPortNo}}, // Peer port is parent's port number
1521 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001522 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1523 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001524 e.Cancel(err)
1525 return
1526 }
1527 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001528 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001529 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001530 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001531}
1532
1533// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001534func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001535
dbainbri4d3a0dc2020-12-02 00:33:42 +00001536 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001537 var err error
1538 /*
1539 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1540 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1541 return nil
1542 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001543 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1544 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001545 e.Cancel(err)
1546 return
1547 }
1548
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001549 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001550 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001551 // reconcilement will be continued after mib download is done
1552 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001553
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001554 /*
1555 ############################################################################
1556 # Setup Alarm handler
1557 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1558 device.serial_number)
1559 ############################################################################
1560 # Setup PM configuration for this device
1561 # Pass in ONU specific options
1562 kwargs = {
1563 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1564 'heartbeat': self.heartbeat,
1565 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1566 }
1567 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1568 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1569 self.logical_device_id, device.serial_number,
1570 grouped=True, freq_override=False, **kwargs)
1571 pm_config = self._pm_metrics.make_proto()
1572 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1573 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1574 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1575
1576 # Note, ONU ID and UNI intf set in add_uni_port method
1577 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1578 ani_ports=[self._pon])
1579
1580 # Code to Run OMCI Test Action
1581 kwargs_omci_test_action = {
1582 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1583 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1584 }
1585 serial_number = device.serial_number
1586 self._test_request = OmciTestRequest(self.core_proxy,
1587 self.omci_agent, self.device_id,
1588 AniG, serial_number,
1589 self.logical_device_id,
1590 exclusive=False,
1591 **kwargs_omci_test_action)
1592
1593 self.enabled = True
1594 else:
1595 self.logger.info('onu-already-activated')
1596 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001597
dbainbri4d3a0dc2020-12-02 00:33:42 +00001598 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001599}
1600
1601// doStateConnected get the device info and update to voltha core
1602// for comparison of the original method (not that easy to uncomment): compare here:
1603// voltha-openolt-adapter/adaptercore/device_handler.go
1604// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001605func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001606
dbainbri4d3a0dc2020-12-02 00:33:42 +00001607 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301608 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001609 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001610 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001611}
1612
1613// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001614func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001615
dbainbri4d3a0dc2020-12-02 00:33:42 +00001616 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301617 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001618 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001619 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001620
1621 /*
1622 // Synchronous call to update device state - this method is run in its own go routine
1623 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1624 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001625 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 +00001626 return err
1627 }
1628 return nil
1629 */
1630}
1631
1632// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001633func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001634
dbainbri4d3a0dc2020-12-02 00:33:42 +00001635 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001636 var err error
1637
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001638 device := dh.device
1639 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001640 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001641 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001642 e.Cancel(err)
1643 return
1644 }
1645
1646 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001648 /*
1649 // Update the all ports state on that device to disable
1650 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001651 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001652 return er
1653 }
1654
1655 //Update the device oper state and connection status
1656 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1657 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1658 dh.device = cloned
1659
1660 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001661 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001662 return er
1663 }
1664
1665 //get the child device for the parent device
1666 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1667 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001668 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001669 return err
1670 }
1671 for _, onuDevice := range onuDevices.Items {
1672
1673 // Update onu state as down in onu adapter
1674 onuInd := oop.OnuIndication{}
1675 onuInd.OperState = "down"
1676 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1677 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1678 if er != nil {
1679 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001680 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001681 //Do not return here and continue to process other ONUs
1682 }
1683 }
1684 // * Discovered ONUs entries need to be cleared , since after OLT
1685 // is up, it starts sending discovery indications again* /
1686 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001687 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001688 return nil
1689 */
Himani Chawla4d908332020-08-31 12:30:20 +05301690 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001691 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001692 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001693}
1694
Himani Chawla6d2ae152020-09-02 13:11:20 +05301695// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001696// #################################################################################
1697
1698// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301699// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001700
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001701//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001702func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001703 dh.lockDevice.RLock()
1704 pOnuDeviceEntry := dh.pOnuOmciDevice
1705 if aWait && pOnuDeviceEntry == nil {
1706 //keep the read sema short to allow for subsequent write
1707 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001708 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001709 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1710 // so it might be needed to wait here for that event with some timeout
1711 select {
1712 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001713 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001714 return nil
1715 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001716 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001717 // if written now, we can return the written value without sema
1718 return dh.pOnuOmciDevice
1719 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001720 }
mpagenko3af1f032020-06-10 08:53:41 +00001721 dh.lockDevice.RUnlock()
1722 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001723}
1724
Himani Chawla6d2ae152020-09-02 13:11:20 +05301725//setOnuDeviceEntry sets the ONU device entry within the handler
1726func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001727 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001728 dh.lockDevice.Lock()
1729 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001730 dh.pOnuOmciDevice = apDeviceEntry
1731 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001732 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301733 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001734 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001735}
1736
Himani Chawla6d2ae152020-09-02 13:11:20 +05301737//addOnuDeviceEntry creates a new ONU device or returns the existing
1738func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001739 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001740
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001742 if deviceEntry == nil {
1743 /* costum_me_map in python code seems always to be None,
1744 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1745 /* also no 'clock' argument - usage open ...*/
1746 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001747 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001748 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001749 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301750 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001751 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001752 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001753 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001754 // fire deviceEntry ready event to spread to possibly waiting processing
1755 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001756 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001757 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001758 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001759 }
1760 // might be updated with some error handling !!!
1761 return nil
1762}
1763
dbainbri4d3a0dc2020-12-02 00:33:42 +00001764func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1765 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001766 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1767
1768 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001769
dbainbri4d3a0dc2020-12-02 00:33:42 +00001770 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001771 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001772 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001773 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1774 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001775 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001776 if err := dh.storePersistentData(ctx); err != nil {
1777 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001778 log.Fields{"device-id": dh.deviceID, "err": err})
1779 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001780 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001781 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001782 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001783 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1784 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001785 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001786 }
1787 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001788 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001789 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001790
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001791 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001792 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001793 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001794 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 +00001795 log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001796 dh.stopReconciling(ctx, true)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001797 } else {
1798 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001799 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001800 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001801 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1802 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1803 // 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 +00001804 // 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 +00001805 // so let's just try to keep it simple ...
1806 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001807 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001808 if err != nil || device == nil {
1809 //TODO: needs to handle error scenarios
1810 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1811 return errors.New("Voltha Device not found")
1812 }
1813 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001814
dbainbri4d3a0dc2020-12-02 00:33:42 +00001815 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001816 return err
mpagenko3af1f032020-06-10 08:53:41 +00001817 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001818
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001819 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001820
1821 /* this might be a good time for Omci Verify message? */
1822 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001823 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001824 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001825 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001826 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001827
1828 /* give the handler some time here to wait for the OMCi verification result
1829 after Timeout start and try MibUpload FSM anyway
1830 (to prevent stopping on just not supported OMCI verification from ONU) */
1831 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001832 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001833 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001834 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001835 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001836 }
1837
1838 /* In py code it looks earlier (on activate ..)
1839 # Code to Run OMCI Test Action
1840 kwargs_omci_test_action = {
1841 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1842 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1843 }
1844 serial_number = device.serial_number
1845 self._test_request = OmciTestRequest(self.core_proxy,
1846 self.omci_agent, self.device_id,
1847 AniG, serial_number,
1848 self.logical_device_id,
1849 exclusive=False,
1850 **kwargs_omci_test_action)
1851 ...
1852 # Start test requests after a brief pause
1853 if not self._test_request_started:
1854 self._test_request_started = True
1855 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1856 reactor.callLater(tststart, self._test_request.start_collector)
1857
1858 */
1859 /* which is then: in omci_test_request.py : */
1860 /*
1861 def start_collector(self, callback=None):
1862 """
1863 Start the collection loop for an adapter if the frequency > 0
1864
1865 :param callback: (callable) Function to call to collect PM data
1866 """
1867 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1868 if callback is None:
1869 callback = self.perform_test_omci
1870
1871 if self.lc is None:
1872 self.lc = LoopingCall(callback)
1873
1874 if self.default_freq > 0:
1875 self.lc.start(interval=self.default_freq / 10)
1876
1877 def perform_test_omci(self):
1878 """
1879 Perform the initial test request
1880 """
1881 ani_g_entities = self._device.configuration.ani_g_entities
1882 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1883 is not None else None
1884 self._entity_id = ani_g_entities_ids[0]
1885 self.logger.info('perform-test', entity_class=self._entity_class,
1886 entity_id=self._entity_id)
1887 try:
1888 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1889 result = yield self._device.omci_cc.send(frame)
1890 if not result.fields['omci_message'].fields['success_code']:
1891 self.logger.info('Self-Test Submitted Successfully',
1892 code=result.fields[
1893 'omci_message'].fields['success_code'])
1894 else:
1895 raise TestFailure('Test Failure: {}'.format(
1896 result.fields['omci_message'].fields['success_code']))
1897 except TimeoutError as e:
1898 self.deferred.errback(failure.Failure(e))
1899
1900 except Exception as e:
1901 self.logger.exception('perform-test-Error', e=e,
1902 class_id=self._entity_class,
1903 entity_id=self._entity_id)
1904 self.deferred.errback(failure.Failure(e))
1905
1906 */
1907
1908 // PM related heartbeat??? !!!TODO....
1909 //self._heartbeat.enabled = True
1910
mpagenko1cc3cb42020-07-27 15:24:38 +00001911 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1912 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1913 * 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 +05301914 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001915 */
1916 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001917 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001918 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001919 if pMibUlFsm.Is(ulStDisabled) {
1920 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001921 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 +00001922 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301923 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001924 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301925 //Determine ONU status and start/re-start MIB Synchronization tasks
1926 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001927 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301928 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001929 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 +00001930 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001931 }
Himani Chawla4d908332020-08-31 12:30:20 +05301932 } else {
1933 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001934 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 +00001935 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301936 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001937 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001938 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001939 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001940 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001941 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001942 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001943 }
1944 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001945 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001946 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001947 }
1948 return nil
1949}
1950
dbainbri4d3a0dc2020-12-02 00:33:42 +00001951func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001952 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001953 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001954 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001955 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001956
mpagenko900ee4b2020-10-12 11:56:34 +00001957 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1958 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1959 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001960 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001961 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001962 log.Fields{"device-id": dh.deviceID, "error": err})
1963 // abort: system behavior is just unstable ...
1964 return err
1965 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001966 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001967 _ = 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 +00001968
1969 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1970 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1971 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001972 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001973 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001974 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001975 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001976 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001977 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001978
1979 //TODO!!! remove existing traffic profiles
1980 /* from py code, if TP's exist, remove them - not yet implemented
1981 self._tp = dict()
1982 # Let TP download happen again
1983 for uni_id in self._tp_service_specific_task:
1984 self._tp_service_specific_task[uni_id].clear()
1985 for uni_id in self._tech_profile_download_done:
1986 self._tech_profile_download_done[uni_id].clear()
1987 */
1988
dbainbri4d3a0dc2020-12-02 00:33:42 +00001989 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001990
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001991 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00001992
dbainbri4d3a0dc2020-12-02 00:33:42 +00001993 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001994 // abort: system behavior is just unstable ...
1995 return err
1996 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001997 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001998 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001999 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00002000 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002001 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002002 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00002003 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002004 // abort: system behavior is just unstable ...
2005 return err
2006 }
2007 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002008 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002009 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002010 return nil
2011}
2012
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002013func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002014 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2015 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2016 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2017 // and using the stop/reset event should never harm
2018
dbainbri4d3a0dc2020-12-02 00:33:42 +00002019 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002020 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002021 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002022 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2023 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002024 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002025 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002026 }
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002027 pDevEntry.mutexOnuImageStatus.RLock()
2028 if pDevEntry.pOnuImageStatus != nil {
2029 pDevEntry.pOnuImageStatus.CancelProcessing(ctx)
2030 }
2031 pDevEntry.mutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002032
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002033 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002034 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002035 }
2036 //MibDownload may run
2037 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2038 if pMibDlFsm != nil {
2039 _ = pMibDlFsm.Event(dlEvReset)
2040 }
2041 //port lock/unlock FSM's may be active
2042 if dh.pUnlockStateFsm != nil {
2043 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2044 }
2045 if dh.pLockStateFsm != nil {
2046 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2047 }
2048 //techProfile related PonAniConfigFsm FSM may be active
2049 if dh.pOnuTP != nil {
2050 // should always be the case here
2051 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
2052 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08002053 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00002054 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002055 }
mpagenko900ee4b2020-10-12 11:56:34 +00002056 }
2057 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002058 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002059 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00002060 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
2061 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002062 dh.lockVlanConfig.RUnlock()
2063 //reset of all Fsm is always accompanied by global persistency data removal
2064 // no need to remove specific data
2065 pVlanFilterFsm.RequestClearPersistency(false)
2066 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002067 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002068 } else {
2069 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002070 }
2071 }
2072 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002073 if dh.getCollectorIsRunning() {
2074 // Stop collector routine
2075 dh.stopCollector <- true
2076 }
Himani Chawla1472c682021-03-17 17:11:14 +05302077 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302078 dh.stopAlarmManager <- true
2079 }
2080
mpagenko80622a52021-02-09 16:53:23 +00002081 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00002082 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002083 dh.lockUpgradeFsm.RLock()
2084 if dh.pOnuUpradeFsm != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00002085 dh.pOnuUpradeFsm.CancelProcessing(ctx)
mpagenko80622a52021-02-09 16:53:23 +00002086 }
2087 dh.lockUpgradeFsm.RUnlock()
2088
mpagenko7d6bb022021-03-11 15:07:55 +00002089 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002090 return nil
2091}
2092
dbainbri4d3a0dc2020-12-02 00:33:42 +00002093func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2094 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 +05302095
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002096 // store persistent data collected during MIB upload processing
2097 if err := dh.storePersistentData(ctx); err != nil {
2098 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2099 log.Fields{"device-id": dh.deviceID, "err": err})
2100 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002101 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002102 dh.addAllUniPorts(ctx)
2103
mpagenkoa40e99a2020-11-17 13:50:39 +00002104 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2105 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2106 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2107 * disable/enable toggling here to allow traffic
2108 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2109 * like the py comment says:
2110 * # start by locking all the unis till mib sync and initial mib is downloaded
2111 * # this way we can capture the port down/up events when we are ready
2112 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302113
mpagenkoa40e99a2020-11-17 13:50:39 +00002114 // Init Uni Ports to Admin locked state
2115 // *** should generate UniLockStateDone event *****
2116 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002117 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002118 } else { //LockStateFSM already init
2119 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002120 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002121 }
2122}
2123
dbainbri4d3a0dc2020-12-02 00:33:42 +00002124func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2125 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302126 /* Mib download procedure -
2127 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2128 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002129 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002130 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002131 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002132 return
2133 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302134 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2135 if pMibDlFsm != nil {
2136 if pMibDlFsm.Is(dlStDisabled) {
2137 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002138 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 +05302139 // maybe try a FSM reset and then again ... - TODO!!!
2140 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002141 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302142 // maybe use more specific states here for the specific download steps ...
2143 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002144 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302145 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002146 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302147 //Begin MIB data download (running autonomously)
2148 }
2149 }
2150 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002151 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002152 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302153 // maybe try a FSM reset and then again ... - TODO!!!
2154 }
2155 /***** Mib download started */
2156 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002157 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302158 }
2159}
2160
dbainbri4d3a0dc2020-12-02 00:33:42 +00002161func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2162 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302163 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002164 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002165 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002166 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002167 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2168 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2169 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2170 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002171 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302172 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
2173 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002174 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302175 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002176 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302177 }
2178 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002179 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302180 log.Fields{"device-id": dh.deviceID})
2181 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002182 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002183
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002184 if !dh.getCollectorIsRunning() {
2185 // Start PM collector routine
2186 go dh.startCollector(ctx)
2187 }
2188 if !dh.getAlarmManagerIsRunning(ctx) {
2189 go dh.startAlarmManager(ctx)
2190 }
2191
Girish Gowdrae0140f02021-02-02 16:55:09 -08002192 // Initialize classical L2 PM Interval Counters
2193 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2194 // There is no way we should be landing here, but if we do then
2195 // there is nothing much we can do about this other than log error
2196 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2197 }
2198
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002199 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002200
2201 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2202 if pDevEntry == nil {
2203 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2204 return
2205 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002206 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002207 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002208 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002209 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2210 log.Fields{"device-id": dh.deviceID})
2211 go dh.reconcileDeviceTechProf(ctx)
2212 // reconcilement will be continued after ani config is done
2213 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002214 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002215 // *** should generate UniUnlockStateDone event *****
2216 if dh.pUnlockStateFsm == nil {
2217 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2218 } else { //UnlockStateFSM already init
2219 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2220 dh.runUniLockFsm(ctx, false)
2221 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302222 }
2223}
2224
dbainbri4d3a0dc2020-12-02 00:33:42 +00002225func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2226 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302227
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002228 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002229 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002230 raisedTs := time.Now().Unix()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002231 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2232 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002233 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002234 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002235 return
2236 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002237 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002238 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002239 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002240 if err := dh.storePersistentData(ctx); err != nil {
2241 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002242 log.Fields{"device-id": dh.deviceID, "err": err})
2243 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302244 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002245 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 +05302246 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002247 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002248 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302249 }
2250}
2251
dbainbri4d3a0dc2020-12-02 00:33:42 +00002252func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2253 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002254 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002255 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00002256 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
2257 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002258 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002259 }
2260
dbainbri4d3a0dc2020-12-02 00:33:42 +00002261 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002262 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002263 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002264
2265 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002266 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002267
dbainbri4d3a0dc2020-12-02 00:33:42 +00002268 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002269 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002270 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002271 return
2272 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002273 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002274 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002275 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002276 if err := dh.storePersistentData(ctx); err != nil {
2277 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002278 log.Fields{"device-id": dh.deviceID, "err": err})
2279 }
mpagenko900ee4b2020-10-12 11:56:34 +00002280}
2281
dbainbri4d3a0dc2020-12-02 00:33:42 +00002282func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2283 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002284 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002285 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002286 voltha.OperStatus_ACTIVE); err != nil {
2287 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002288 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002289 }
2290
dbainbri4d3a0dc2020-12-02 00:33:42 +00002291 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002292 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002293 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002294 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002295
2296 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002297 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002298
dbainbri4d3a0dc2020-12-02 00:33:42 +00002299 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002300 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002301 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002302 return
2303 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002304 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002305 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002306 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002307 if err := dh.storePersistentData(ctx); err != nil {
2308 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002309 log.Fields{"device-id": dh.deviceID, "err": err})
2310 }
mpagenko900ee4b2020-10-12 11:56:34 +00002311}
2312
dbainbri4d3a0dc2020-12-02 00:33:42 +00002313func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002314 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002315 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002316 // attention: the device reason update is done based on ONU-UNI-Port related activity
2317 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002318 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002319 // 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 +00002320 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302321 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002322 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002323 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002324 }
2325 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002326 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002327 // attention: the device reason update is done based on ONU-UNI-Port related activity
2328 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002329 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002330 // 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 +00002331 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002332 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002333 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302334}
2335
dbainbri4d3a0dc2020-12-02 00:33:42 +00002336func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2337 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002338 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302339 // attention: the device reason update is done based on ONU-UNI-Port related activity
2340 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302341
mpagenkof1fc3862021-02-16 10:09:52 +00002342 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002343 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002344 // which may be the case from some previous actvity on another UNI Port of the ONU
2345 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002346 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2347 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002348 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002349 }
2350 }
2351 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002352 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002353 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002354 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002355 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302356 }
mpagenkof1fc3862021-02-16 10:09:52 +00002357
2358 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2359 //events that request KvStore write
2360 if err := dh.storePersistentData(ctx); err != nil {
2361 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2362 log.Fields{"device-id": dh.deviceID, "err": err})
2363 }
2364 } else {
2365 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2366 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002367 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302368}
2369
Himani Chawla6d2ae152020-09-02 13:11:20 +05302370//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002371func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302372 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002373 case MibDatabaseSync:
2374 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002375 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002376 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002377 case UniLockStateDone:
2378 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002379 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002380 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002381 case MibDownloadDone:
2382 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002383 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002384 }
2385 case UniUnlockStateDone:
2386 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002387 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002388 }
mpagenko900ee4b2020-10-12 11:56:34 +00002389 case UniEnableStateDone:
2390 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002391 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002392 }
2393 case UniDisableStateDone:
2394 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002395 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002396 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002397 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002398 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002399 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002400 }
mpagenkof1fc3862021-02-16 10:09:52 +00002401 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002402 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002403 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002404 }
mpagenkoaa3afe92021-05-21 16:20:58 +00002405 case OmciOnuSwUpgradeDone:
2406 {
2407 dh.upgradeSuccess = true
2408 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002409 default:
2410 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002411 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002412 }
2413 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002414}
2415
dbainbri4d3a0dc2020-12-02 00:33:42 +00002416func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002417 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002418 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302419 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002420 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002421 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002422 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302423 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002424 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002425 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002426 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002427 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002428 //store UniPort with the System-PortNumber key
2429 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002430 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002431 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002432 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2433 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002434 } //error logging already within UniPort method
2435 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002436 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002437 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002438 }
2439 }
2440}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002441
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002442func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2443 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2444 if pDevEntry == nil {
2445 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2446 return
2447 }
2448 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2449 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2450 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2451 for _, mgmtEntityID := range pptpInstKeys {
2452 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2453 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2454 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2455 i++
2456 }
2457 } else {
2458 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2459 }
2460 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2461 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2462 for _, mgmtEntityID := range veipInstKeys {
2463 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2464 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2465 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2466 i++
2467 }
2468 } else {
2469 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2470 }
2471 if i == 0 {
2472 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2473 }
2474}
2475
mpagenko3af1f032020-06-10 08:53:41 +00002476// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002477func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002478 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302479 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002480 // with following remark:
2481 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2482 // # load on the core
2483
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002484 // 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 +00002485
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002486 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002487 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002488 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002489 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302490 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002491 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002492 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002493 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 +00002494 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002495 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002496 }
mpagenko3af1f032020-06-10 08:53:41 +00002497 }
2498 }
2499}
2500
2501// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002502func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002503 // compare enableUniPortStateUpdate() above
2504 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2505 for uniNo, uniPort := range dh.uniEntityMap {
2506 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002507
2508 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002509 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302510 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002511 if !dh.isReconciling() {
2512 //maybe also use getter functions on uniPort - perhaps later ...
2513 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2514 } else {
2515 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2516 }
2517
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002518 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002519 }
2520}
2521
2522// ONU_Active/Inactive announcement on system KAFKA bus
2523// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002524func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002525 var de voltha.DeviceEvent
2526 eventContext := make(map[string]string)
2527 //Populating event context
2528 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002529 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002530 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002531 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302532 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002533 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 +00002534 }
2535 oltSerialNumber := parentDevice.SerialNumber
2536
2537 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2538 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2539 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302540 eventContext["olt-serial-number"] = oltSerialNumber
2541 eventContext["device-id"] = aDeviceID
2542 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002543 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
2544 if deviceEntry := dh.getOnuDeviceEntry(ctx, false); deviceEntry != nil {
2545 deviceEntry.mutexPersOnuConfig.RLock()
2546 eventContext["equipment-id"] = deviceEntry.sOnuPersistentData.PersEquipmentID
2547 deviceEntry.mutexPersOnuConfig.RUnlock()
2548 eventContext["software-version"] = deviceEntry.getActiveImageVersion(ctx)
2549 deviceEntry.mutexPersOnuConfig.RLock()
2550 eventContext["vendor"] = deviceEntry.sOnuPersistentData.PersVendorID
2551 deviceEntry.mutexPersOnuConfig.RUnlock()
2552 eventContext["inactive-software-version"] = deviceEntry.getInactiveImageVersion(ctx)
2553 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2554 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2555 } else {
2556 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2557 log.Fields{"device-id": aDeviceID})
2558 return
2559 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002560
2561 /* Populating device event body */
2562 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302563 de.ResourceId = aDeviceID
2564 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002565 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2566 de.Description = fmt.Sprintf("%s Event - %s - %s",
2567 cEventObjectType, cOnuActivatedEvent, "Raised")
2568 } else {
2569 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2570 de.Description = fmt.Sprintf("%s Event - %s - %s",
2571 cEventObjectType, cOnuActivatedEvent, "Cleared")
2572 }
2573 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002574 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2575 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302576 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002577 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002578 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302579 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002580}
2581
Himani Chawla4d908332020-08-31 12:30:20 +05302582// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002583func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002584 chLSFsm := make(chan Message, 2048)
2585 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302586 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002587 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002588 sFsmName = "LockStateFSM"
2589 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002590 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002591 sFsmName = "UnLockStateFSM"
2592 }
mpagenko3af1f032020-06-10 08:53:41 +00002593
dbainbri4d3a0dc2020-12-02 00:33:42 +00002594 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002595 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002596 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002597 return
2598 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002599 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002600 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002601 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302602 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002603 dh.pLockStateFsm = pLSFsm
2604 } else {
2605 dh.pUnlockStateFsm = pLSFsm
2606 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002607 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002608 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002609 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002610 }
2611}
2612
2613// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002614func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002615 /* Uni Port lock/unlock procedure -
2616 ***** should run via 'adminDone' state and generate the argument requested event *****
2617 */
2618 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302619 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002620 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2621 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2622 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002623 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302624 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002625 }
2626 } else {
2627 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2628 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2629 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002630 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302631 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002632 }
2633 }
2634 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002635 if pLSStatemachine.Is(uniStDisabled) {
2636 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002637 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002638 // maybe try a FSM reset and then again ... - TODO!!!
2639 } else {
2640 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002641 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002642 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002643 }
2644 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002645 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002646 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002647 // maybe try a FSM reset and then again ... - TODO!!!
2648 }
2649 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002650 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002651 // maybe try a FSM reset and then again ... - TODO!!!
2652 }
2653}
2654
mpagenko80622a52021-02-09 16:53:23 +00002655// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002656func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002657 //in here lockUpgradeFsm is already locked
2658 chUpgradeFsm := make(chan Message, 2048)
2659 var sFsmName = "OnuSwUpgradeFSM"
2660 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002661 if apDevEntry.PDevOmciCC == nil {
2662 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2663 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002664 }
mpagenko15ff4a52021-03-02 10:09:20 +00002665 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002666 sFsmName, chUpgradeFsm)
2667 if dh.pOnuUpradeFsm != nil {
2668 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2669 if pUpgradeStatemachine != nil {
2670 if pUpgradeStatemachine.Is(upgradeStDisabled) {
mpagenkoaa3afe92021-05-21 16:20:58 +00002671 dh.upgradeSuccess = false //for start of upgrade processing reset the last indication
mpagenko80622a52021-02-09 16:53:23 +00002672 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2673 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2674 // maybe try a FSM reset and then again ... - TODO!!!
2675 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2676 }
2677 /***** LockStateFSM started */
2678 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2679 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2680 } else {
2681 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2682 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2683 // maybe try a FSM reset and then again ... - TODO!!!
2684 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2685 }
2686 } else {
2687 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2688 // maybe try a FSM reset and then again ... - TODO!!!
2689 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2690 }
2691 } else {
2692 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2693 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2694 }
2695 return nil
2696}
2697
2698// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2699func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2700 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2701 "device-id": dh.deviceID})
2702 dh.lockUpgradeFsm.Lock()
2703 defer dh.lockUpgradeFsm.Unlock()
2704 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2705}
2706
mpagenko15ff4a52021-03-02 10:09:20 +00002707// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2708func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2709 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2710 if pDevEntry == nil {
2711 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2712 return
2713 }
2714
2715 dh.lockUpgradeFsm.RLock()
2716 defer dh.lockUpgradeFsm.RUnlock()
2717 if dh.pOnuUpradeFsm != nil {
2718 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2719 if pUpgradeStatemachine != nil {
2720 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2721 // (some manual forced commit could do without)
mpagenko1f8e8822021-06-25 14:10:21 +00002722 upgradeState := pUpgradeStatemachine.Current()
2723 if (upgradeState == upgradeStWaitForCommit) ||
2724 (upgradeState == upgradeStRequestingActivate) {
2725 // also include upgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00002726 // 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 +00002727 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00002728 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
2729 if errImg != nil {
2730 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
2731 log.Fields{"device-id": dh.deviceID})
2732 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
mpagenko15ff4a52021-03-02 10:09:20 +00002733 return
2734 }
mpagenko1f8e8822021-06-25 14:10:21 +00002735 if activeImageID == dh.pOnuUpradeFsm.inactiveImageMeID {
2736 if (upgradeState == upgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
2737 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
2738 if err := pUpgradeStatemachine.Event(upgradeEvActivationDone); err != nil {
2739 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
2740 return
2741 }
2742 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
2743 "state": upgradeState, "device-id": dh.deviceID})
2744 } else {
2745 //FSM in waitForCommit or (upgradeStRequestingActivate [lost ActivateResp] and commit allowed)
2746 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2747 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2748 return
2749 }
2750 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2751 "state": upgradeState, "device-id": dh.deviceID})
2752 }
2753 } else {
2754 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit/on ActivateResponse, but load did not start with expected image Id",
2755 log.Fields{"device-id": dh.deviceID})
2756 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2757 return
2758 }
mpagenko15ff4a52021-03-02 10:09:20 +00002759 } else {
2760 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2761 log.Fields{"device-id": dh.deviceID})
2762 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2763 return
2764 }
mpagenko183647c2021-06-08 15:25:04 +00002765 } else {
2766 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2767 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2768 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2769 if dh.pOnuUpradeFsm.inactiveImageMeID == activeImageID {
2770 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2771 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2772 dh.pOnuUpradeFsm.SetImageState(ctx, voltha.ImageState_IMAGE_ACTIVE)
2773 }
2774 }
mpagenko15ff4a52021-03-02 10:09:20 +00002775 }
2776 }
2777 } else {
2778 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2779 }
2780}
2781
Himani Chawla6d2ae152020-09-02 13:11:20 +05302782//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002783func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002784
2785 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002786 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07002787 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00002788 kvbackend := &db.Backend{
2789 Client: dh.pOpenOnuAc.kvClient,
2790 StoreType: dh.pOpenOnuAc.KVStoreType,
2791 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002792 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002793 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2794 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002795
mpagenkoaf801632020-07-03 10:00:42 +00002796 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002797}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002798func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302799 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002800
mpagenkodff5dda2020-08-28 11:52:01 +00002801 for _, field := range flow.GetOfbFields(apFlowItem) {
2802 switch field.Type {
2803 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2804 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002805 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002806 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2807 }
mpagenko01e726e2020-10-23 09:45:29 +00002808 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002809 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2810 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302811 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002812 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302813 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2814 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002815 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2816 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002817 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2818 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302819 return
mpagenkodff5dda2020-08-28 11:52:01 +00002820 }
2821 }
mpagenko01e726e2020-10-23 09:45:29 +00002822 */
mpagenkodff5dda2020-08-28 11:52:01 +00002823 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2824 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302825 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002826 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302827 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002828 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302829 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002830 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002831 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302832 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002833 }
2834 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2835 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302836 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002837 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002838 "PCP": loAddPcp})
2839 }
2840 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2841 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002842 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002843 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2844 }
2845 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2846 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002847 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002848 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2849 }
2850 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2851 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002852 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002853 "IPv4-DST": field.GetIpv4Dst()})
2854 }
2855 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2856 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002857 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002858 "IPv4-SRC": field.GetIpv4Src()})
2859 }
2860 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2861 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002862 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002863 "Metadata": field.GetTableMetadata()})
2864 }
2865 /*
2866 default:
2867 {
2868 //all other entires ignored
2869 }
2870 */
2871 }
2872 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302873}
mpagenkodff5dda2020-08-28 11:52:01 +00002874
dbainbri4d3a0dc2020-12-02 00:33:42 +00002875func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002876 for _, action := range flow.GetActions(apFlowItem) {
2877 switch action.Type {
2878 /* not used:
2879 case of.OfpActionType_OFPAT_OUTPUT:
2880 {
mpagenko01e726e2020-10-23 09:45:29 +00002881 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002882 "Output": action.GetOutput()})
2883 }
2884 */
2885 case of.OfpActionType_OFPAT_PUSH_VLAN:
2886 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002887 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002888 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2889 }
2890 case of.OfpActionType_OFPAT_SET_FIELD:
2891 {
2892 pActionSetField := action.GetSetField()
2893 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002894 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002895 "OxcmClass": pActionSetField.Field.OxmClass})
2896 }
2897 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302898 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002899 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302900 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002901 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302902 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002903 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302904 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002905 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002906 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002907 "Type": pActionSetField.Field.GetOfbField().Type})
2908 }
2909 }
2910 /*
2911 default:
2912 {
2913 //all other entires ignored
2914 }
2915 */
2916 }
2917 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302918}
2919
2920//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
ozgecanetsia82b91a62021-05-21 18:54:49 +03002921func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort,
2922 apFlowMetaData *voltha.FlowMetadata) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302923 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2924 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2925 var loAddPcp, loSetPcp uint8
2926 var loIPProto uint32
2927 /* the TechProfileId is part of the flow Metadata - compare also comment within
2928 * OLT-Adapter:openolt_flowmgr.go
2929 * Metadata 8 bytes:
2930 * Most Significant 2 Bytes = Inner VLAN
2931 * Next 2 Bytes = Tech Profile ID(TPID)
2932 * Least Significant 4 Bytes = Port ID
2933 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2934 * subscriber related flows.
2935 */
2936
dbainbri4d3a0dc2020-12-02 00:33:42 +00002937 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302938 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002939 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302940 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002941 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302942 }
mpagenko551a4d42020-12-08 18:09:20 +00002943 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002944 loCookie := apFlowItem.GetCookie()
2945 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002946 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002947 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302948
dbainbri4d3a0dc2020-12-02 00:33:42 +00002949 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002950 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302951 if loIPProto == 2 {
2952 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2953 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002954 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2955 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302956 return nil
2957 }
mpagenko01e726e2020-10-23 09:45:29 +00002958 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002959 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002960
2961 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002962 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002963 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2964 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2965 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2966 //TODO!!: Use DeviceId within the error response to rwCore
2967 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002968 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002969 }
2970 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002971 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002972 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2973 } else {
2974 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2975 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2976 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302977 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002978 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002979 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002980 }
mpagenko9a304ea2020-12-16 15:54:01 +00002981
2982 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002983 dh.lockVlanConfig.RLock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03002984 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID, "tpID": loTpID, "uniID": apUniPort.uniID})
2985 var meter *voltha.OfpMeterConfig
2986 if apFlowMetaData != nil {
2987 meter = apFlowMetaData.Meters[0]
2988 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302989 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002990 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03002991 loMatchVlan, loSetVlan, loSetPcp, false, meter)
mpagenkof1fc3862021-02-16 10:09:52 +00002992 dh.lockVlanConfig.RUnlock()
2993 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002994 }
mpagenkof1fc3862021-02-16 10:09:52 +00002995 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002996 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03002997 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false, meter)
mpagenko01e726e2020-10-23 09:45:29 +00002998}
2999
3000//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00003001func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00003002 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3003 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3004 //no extra check is done on the rule parameters
3005 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3006 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3007 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3008 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003009 // - 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 +00003010 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003011 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003012
3013 /* TT related temporary workaround - should not be needed anymore
3014 for _, field := range flow.GetOfbFields(apFlowItem) {
3015 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3016 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00003017 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003018 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3019 if loIPProto == 2 {
3020 // 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 +00003021 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00003022 log.Fields{"device-id": dh.deviceID})
3023 return nil
3024 }
3025 }
3026 } //for all OfbFields
3027 */
3028
mpagenko9a304ea2020-12-16 15:54:01 +00003029 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003030 dh.lockVlanConfig.RLock()
3031 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00003032 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003033 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00003034 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003035 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00003036 log.Fields{"device-id": dh.deviceID})
3037 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003038 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00003039 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00003040
mpagenko01e726e2020-10-23 09:45:29 +00003041 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00003042}
3043
Himani Chawla26e555c2020-08-31 12:30:20 +05303044// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003045// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00003046func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003047 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
mpagenkodff5dda2020-08-28 11:52:01 +00003048 chVlanFilterFsm := make(chan Message, 2048)
3049
dbainbri4d3a0dc2020-12-02 00:33:42 +00003050 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003051 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003052 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303053 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003054 }
3055
dbainbri4d3a0dc2020-12-02 00:33:42 +00003056 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00003057 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003058 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter)
mpagenkodff5dda2020-08-28 11:52:01 +00003059 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003060 dh.lockVlanConfig.Lock()
mpagenko7d6bb022021-03-11 15:07:55 +00003061 //ensure the mutex is locked throughout the state transition to 'starting' to prevent unintended (ignored) events to be sent there
3062 // (from parallel processing)
3063 defer dh.lockVlanConfig.Unlock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303064 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003065 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3066 if pVlanFilterStatemachine != nil {
3067 if pVlanFilterStatemachine.Is(vlanStDisabled) {
3068 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003069 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05303070 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003071 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303072 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003073 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05303074 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3075 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003076 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003077 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003078 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303079 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003080 }
3081 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003082 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003083 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303084 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003085 }
3086 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003087 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003088 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05303089 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003090 }
3091 return nil
3092}
3093
mpagenkofc4f56e2020-11-04 17:17:49 +00003094//VerifyVlanConfigRequest checks on existence of a given uniPort
3095// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003096func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003097 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
3098 var pCurrentUniPort *onuUniPort
3099 for _, uniPort := range dh.uniEntityMap {
3100 // only if this port is validated for operState transfer
3101 if uniPort.uniID == uint8(aUniID) {
3102 pCurrentUniPort = uniPort
3103 break //found - end search loop
3104 }
3105 }
3106 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003107 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00003108 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
3109 return
3110 }
mpagenko551a4d42020-12-08 18:09:20 +00003111 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003112}
3113
mpagenkodff5dda2020-08-28 11:52:01 +00003114//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00003115func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003116 //TODO!! verify and start pending flow configuration
3117 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3118 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003119
3120 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303121 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003122 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003123 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
3124 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3125 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003126 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
3127 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
3128 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
3129 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
3130 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3131 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3132 } else {
3133 /***** UniVlanConfigFsm continued */
3134 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
3135 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3136 "UniPort": apUniPort.portNo})
3137 }
3138 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
3139 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
3140 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3141 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3142 } else {
3143 /***** UniVlanConfigFsm continued */
3144 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3145 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3146 "UniPort": apUniPort.portNo})
3147 }
mpagenkodff5dda2020-08-28 11:52:01 +00003148 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003149 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3150 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003151 "UniPort": apUniPort.portNo})
3152 }
3153 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003154 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3155 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3156 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003157 }
3158 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003159 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003160 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003161 }
mpagenkof1fc3862021-02-16 10:09:52 +00003162 } else {
3163 dh.lockVlanConfig.RUnlock()
3164 }
mpagenkodff5dda2020-08-28 11:52:01 +00003165}
3166
3167//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3168// 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 +00003169func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3170 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003171 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3172 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003173 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303174 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003175 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003176}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003177
mpagenkof1fc3862021-02-16 10:09:52 +00003178//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3179func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3180 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3181 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3182 // obviously then parallel processing on the cancel must be avoided
3183 // deadline context to ensure completion of background routines waited for
3184 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3185 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3186 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3187
3188 aPDevEntry.resetKvProcessingErrorIndication()
3189 var wg sync.WaitGroup
3190 wg.Add(1) // for the 1 go routine to finish
3191
3192 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3193 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3194
3195 return aPDevEntry.getKvProcessingErrorIndication()
3196}
3197
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003198//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3199//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003200func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3201 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003202
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003203 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003204 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003205 return nil
3206 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003207 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003208
dbainbri4d3a0dc2020-12-02 00:33:42 +00003209 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003210 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003211 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003212 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3213 }
3214 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3215
mpagenkof1fc3862021-02-16 10:09:52 +00003216 if aWriteToKvStore {
3217 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3218 }
3219 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003220}
3221
dbainbri4d3a0dc2020-12-02 00:33:42 +00003222func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003223 defer cancel() //ensure termination of context (may be pro forma)
3224 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003225 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003226 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003227}
3228
dbainbri4d3a0dc2020-12-02 00:33:42 +00003229func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003230
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003231 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003232 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003233 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003234 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3235 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003236 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003237 return err
3238 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003239 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003240 return nil
3241 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003242 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003243 return nil
3244}
3245
dbainbri4d3a0dc2020-12-02 00:33:42 +00003246func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3247 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003248 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003249 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003250 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3251 }
mpagenkof1fc3862021-02-16 10:09:52 +00003252 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003253}
3254
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003255func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
3256 var errStr string = ""
3257 for _, err := range errS {
3258 if err != nil {
3259 errStr = errStr + err.Error() + " "
3260 }
3261 }
3262 if errStr != "" {
3263 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
3264 }
3265 return nil
3266}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003267
3268// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003269// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003270func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3271 dh.lockDevice.RLock()
3272 defer dh.lockDevice.RUnlock()
3273 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3274 return uniPort.entityID, nil
3275 }
3276 return 0, errors.New("error-fetching-uni-port")
3277}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003278
3279// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003280func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3281 var errorsList []error
3282 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 -08003283
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003284 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3285 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3286 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3287
3288 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3289 // successfully.
3290 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3291 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3292 if len(errorsList) > 0 {
3293 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3294 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003295 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003296 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3297 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003298}
3299
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003300func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3301 var err error
3302 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003303 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003304
3305 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3306 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3307 errorsList = append(errorsList, err)
3308 }
3309 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003310 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003311
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003312 return errorsList
3313}
3314
3315func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3316 var err error
3317 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003318 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003319 // Check if group metric related config is updated
3320 for _, v := range pmConfigs.Groups {
3321 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3322 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3323 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3324
3325 if ok && m.frequency != v.GroupFreq {
3326 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3327 errorsList = append(errorsList, err)
3328 }
3329 }
3330 if ok && m.enabled != v.Enabled {
3331 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3332 errorsList = append(errorsList, err)
3333 }
3334 }
3335 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003336 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003337 return errorsList
3338}
3339
3340func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3341 var err error
3342 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003343 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003344 // Check if standalone metric related config is updated
3345 for _, v := range pmConfigs.Metrics {
3346 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003347 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003348 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3349
3350 if ok && m.frequency != v.SampleFreq {
3351 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3352 errorsList = append(errorsList, err)
3353 }
3354 }
3355 if ok && m.enabled != v.Enabled {
3356 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3357 errorsList = append(errorsList, err)
3358 }
3359 }
3360 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003361 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003362 return errorsList
3363}
3364
3365// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003366func (dh *deviceHandler) startCollector(ctx context.Context) {
3367 logger.Debugf(ctx, "startingCollector")
3368
3369 // Start routine to process OMCI GET Responses
3370 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303371 // Create Extended Frame PM ME
3372 go dh.pOnuMetricsMgr.createEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003373 // Initialize the next metric collection time.
3374 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3375 // reset like onu rebooted.
3376 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003377 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003378 for {
3379 select {
3380 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003381 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003382 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003383 // Stop the L2 PM FSM
3384 go func() {
3385 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3386 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3387 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3388 }
3389 } else {
3390 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3391 }
3392 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003393 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3394 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3395 }
3396 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3397 dh.pOnuMetricsMgr.stopTicks <- true
3398 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003399
Girish Gowdrae09a6202021-01-12 18:10:59 -08003400 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003401 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3402 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3403 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3404 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3405 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003406 // Update the next metric collection time.
3407 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003408 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003409 } else {
3410 if dh.pmConfigs.Grouped { // metrics are managed as a group
3411 // parse through the group and standalone metrics to see it is time to collect their metrics
3412 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003413
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003414 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3415 // 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 -08003416 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3417 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003418 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3419 }
3420 }
3421 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3422 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3423 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3424 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3425 }
3426 }
3427 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3428
3429 // parse through the group and update the next metric collection time
3430 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3431 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3432 // 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 -08003433 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3434 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003435 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3436 }
3437 }
3438 // parse through the standalone metrics and update the next metric collection time
3439 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3440 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3441 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3442 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3443 }
3444 }
3445 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3446 } /* else { // metrics are not managed as a group
3447 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3448 } */
3449 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003450 }
3451 }
3452}
kesavandfdf77632021-01-26 23:40:33 -05003453
3454func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3455
3456 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3457 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3458}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003459
Himani Chawla43f95ff2021-06-03 00:24:12 +05303460func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3461 if dh.pOnuMetricsMgr == nil {
3462 return &extension.SingleGetValueResponse{
3463 Response: &extension.GetValueResponse{
3464 Status: extension.GetValueResponse_ERROR,
3465 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3466 },
3467 }
3468 }
3469 resp := dh.pOnuMetricsMgr.collectEthernetFrameExtendedPMCounters(ctx)
3470 return resp
3471}
3472
mpagenkof1fc3862021-02-16 10:09:52 +00003473func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3474 if pFsm == nil {
3475 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003476 }
mpagenkof1fc3862021-02-16 10:09:52 +00003477 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003478}
3479
mpagenkof1fc3862021-02-16 10:09:52 +00003480func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3481 var pFsm *fsm.FSM
3482 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3483 switch omciFsm {
3484 case cUploadFsm:
3485 {
3486 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3487 }
3488 case cDownloadFsm:
3489 {
3490 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3491 }
3492 case cUniLockFsm:
3493 {
3494 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3495 }
3496 case cUniUnLockFsm:
3497 {
3498 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3499 }
3500 case cL2PmFsm:
3501 {
3502 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3503 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3504 } else {
3505 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003506 }
3507 }
mpagenko80622a52021-02-09 16:53:23 +00003508 case cOnuUpgradeFsm:
3509 {
3510 dh.lockUpgradeFsm.RLock()
3511 defer dh.lockUpgradeFsm.RUnlock()
3512 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3513 }
mpagenkof1fc3862021-02-16 10:09:52 +00003514 default:
3515 {
3516 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3517 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3518 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003519 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003520 }
mpagenkof1fc3862021-02-16 10:09:52 +00003521 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003522}
3523
mpagenkof1fc3862021-02-16 10:09:52 +00003524func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3525 for _, v := range dh.pOnuTP.pAniConfigFsm {
3526 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003527 return false
3528 }
3529 }
3530 return true
3531}
3532
mpagenkof1fc3862021-02-16 10:09:52 +00003533func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3534 dh.lockVlanConfig.RLock()
3535 defer dh.lockVlanConfig.RUnlock()
3536 for _, v := range dh.UniVlanConfigFsmMap {
3537 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3538 return false
3539 }
3540 }
3541 return true //FSM not active - so there is no activity on omci
3542}
3543
3544func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3545 dh.lockVlanConfig.RLock()
3546 defer dh.lockVlanConfig.RUnlock()
3547 for _, v := range dh.UniVlanConfigFsmMap {
3548 if v.pAdaptFsm.pFsm != nil {
3549 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3550 return true //there is at least one VLAN FSM with some active configuration
3551 }
3552 }
3553 }
3554 return false //there is no VLAN FSM with some active configuration
3555}
3556
3557func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3558 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3559 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3560 return false
3561 }
3562 }
3563 // a further check is done to identify, if at least some data traffic related configuration exists
3564 // 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])
3565 return dh.checkUserServiceExists(ctx)
3566}
3567
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003568func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3569 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3570 if err := dh.resetFsms(ctx, false); err != nil {
3571 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3572 // TODO: fatal error reset ONU, delete deviceHandler!
3573 return
3574 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003575 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003576 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003577}
3578
3579func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3580 dh.mutexCollectorFlag.Lock()
3581 dh.collectorIsRunning = flagValue
3582 dh.mutexCollectorFlag.Unlock()
3583}
3584
3585func (dh *deviceHandler) getCollectorIsRunning() bool {
3586 dh.mutexCollectorFlag.RLock()
3587 flagValue := dh.collectorIsRunning
3588 dh.mutexCollectorFlag.RUnlock()
3589 return flagValue
3590}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303591
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303592func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3593 dh.mutextAlarmManagerFlag.Lock()
3594 dh.alarmManagerIsRunning = flagValue
3595 dh.mutextAlarmManagerFlag.Unlock()
3596}
3597
Himani Chawla1472c682021-03-17 17:11:14 +05303598func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303599 dh.mutextAlarmManagerFlag.RLock()
3600 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303601 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303602 dh.mutextAlarmManagerFlag.RUnlock()
3603 return flagValue
3604}
3605
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303606func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3607 logger.Debugf(ctx, "startingAlarmManager")
3608
3609 // Start routine to process OMCI GET Responses
3610 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303611 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303612 if stop := <-dh.stopAlarmManager; stop {
3613 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303614 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303615 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303616 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3617 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3618 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303619 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303620 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303621 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3622 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303623 }
3624}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003625
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003626func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003627 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003628
Maninder7961d722021-06-16 22:10:28 +05303629 connectStatus := voltha.ConnectStatus_UNREACHABLE
3630 operState := voltha.OperStatus_UNKNOWN
3631
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003632 if !dh.isReconciling() {
3633 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003634 logger.Debugw(ctx, "wait for channel signal or timeout",
3635 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003636 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003637 case success := <-dh.chReconcilingFinished:
3638 if success {
Maninderb5187552021-03-23 22:23:42 +05303639 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3640 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3641 log.Fields{"device-id": dh.deviceID})
3642 } else {
Maninderb5187552021-03-23 22:23:42 +05303643 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3644 connectStatus = voltha.ConnectStatus_REACHABLE
3645 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3646 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3647 operState = voltha.OperStatus_ACTIVE
3648 } else {
3649 operState = voltha.OperStatus_ACTIVATING
3650 }
3651 }
3652 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3653 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3654 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3655 operState = voltha.OperStatus_DISCOVERED
3656 }
3657
3658 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303659 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003660 logger.Debugw(ctx, "reconciling has been finished in time",
3661 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303662 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, operState); err != nil {
3663 logger.Errorw(ctx, "unable to update device state to core",
3664 log.Fields{"device-id": dh.deviceID, "Err": err})
3665 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003666 } else {
Maninderb5187552021-03-23 22:23:42 +05303667 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003668 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303669
3670 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3671 logger.Errorw(ctx, "No valid OnuDevice",
3672 log.Fields{"device-id": dh.deviceID})
3673 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3674 connectStatus = voltha.ConnectStatus_REACHABLE
3675 }
3676
3677 dh.deviceReconcileFailedUpdate(ctx, drReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003678 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003679 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003680 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3681 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303682
3683 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3684 logger.Errorw(ctx, "No valid OnuDevice",
3685 log.Fields{"device-id": dh.deviceID})
3686 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3687 connectStatus = voltha.ConnectStatus_REACHABLE
3688 }
3689
3690 dh.deviceReconcileFailedUpdate(ctx, drReconcileMaxTimeout, connectStatus)
3691
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003692 }
3693 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003694 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003695 dh.mutexReconcilingFlag.Unlock()
3696 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003697 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003698 dh.mutexReconcilingFlag.Lock()
3699 if skipOnuConfig {
3700 dh.reconciling = cSkipOnuConfigReconciling
3701 } else {
3702 dh.reconciling = cOnuConfigReconciling
3703 }
3704 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003705}
3706
Girish Gowdra50e56422021-06-01 16:46:04 -07003707func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool) {
3708 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID, "success": success})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003709 if dh.isReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07003710 dh.chReconcilingFinished <- success
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003711 } else {
3712 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3713 }
3714}
3715
3716func (dh *deviceHandler) isReconciling() bool {
3717 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003718 defer dh.mutexReconcilingFlag.RUnlock()
3719 return dh.reconciling != cNoReconciling
3720}
3721
3722func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3723 dh.mutexReconcilingFlag.RLock()
3724 defer dh.mutexReconcilingFlag.RUnlock()
3725 return dh.reconciling == cSkipOnuConfigReconciling
3726}
3727
3728func (dh *deviceHandler) setDeviceReason(value uint8) {
3729 dh.mutexDeviceReason.Lock()
3730 dh.deviceReason = value
3731 dh.mutexDeviceReason.Unlock()
3732}
3733
3734func (dh *deviceHandler) getDeviceReason() uint8 {
3735 dh.mutexDeviceReason.RLock()
3736 value := dh.deviceReason
3737 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003738 return value
3739}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003740
3741func (dh *deviceHandler) getDeviceReasonString() string {
3742 return deviceReasonMap[dh.getDeviceReason()]
3743}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003744
3745func (dh *deviceHandler) setReconcilingFlows(value bool) {
3746 dh.mutexReconcilingFlowsFlag.Lock()
3747 dh.reconcilingFlows = value
3748 dh.mutexReconcilingFlowsFlag.Unlock()
3749}
3750
3751func (dh *deviceHandler) isReconcilingFlows() bool {
3752 dh.mutexReconcilingFlowsFlag.RLock()
3753 value := dh.reconcilingFlows
3754 dh.mutexReconcilingFlowsFlag.RUnlock()
3755 return value
3756}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003757
3758func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3759 dh.mutexReadyForOmciConfig.Lock()
3760 dh.readyForOmciConfig = flagValue
3761 dh.mutexReadyForOmciConfig.Unlock()
3762}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003763func (dh *deviceHandler) isReadyForOmciConfig() bool {
3764 dh.mutexReadyForOmciConfig.RLock()
3765 flagValue := dh.readyForOmciConfig
3766 dh.mutexReadyForOmciConfig.RUnlock()
3767 return flagValue
3768}
Maninder7961d722021-06-16 22:10:28 +05303769
3770func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
3771 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
3772 logger.Errorw(ctx, "unable to update device reason to core",
3773 log.Fields{"device-id": dh.deviceID, "Err": err})
3774 }
3775
3776 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
3777 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, voltha.OperStatus_RECONCILING_FAILED); err != nil {
3778 logger.Errorw(ctx, "unable to update device state to core",
3779 log.Fields{"device-id": dh.deviceID, "Err": err})
3780 }
3781}