blob: edb44ce5211bbf3cb98fb93361f2c4c9bc8c4798 [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
476 if dh.pOnuTP == nil {
477 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000478 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530479 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000480 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530481 }
482
483 msgBody := msg.GetBody()
484 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
485 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000486 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530487 "device-id": dh.deviceID, "error": err})
488 return err
489 }
490
491 //compare TECH_PROFILE_DOWNLOAD_REQUEST
492 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000493 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530494
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000495 if delGemPortMsg.UniId > 255 {
496 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
497 delGemPortMsg.UniId, dh.deviceID))
498 }
499 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700500 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800501 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700502 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 -0800503 return err
504 }
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700505 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000506 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000507
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700508 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
509 cResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000510
Himani Chawla26e555c2020-08-31 12:30:20 +0530511}
512
Himani Chawla6d2ae152020-09-02 13:11:20 +0530513func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000514 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530515 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000516
dbainbri4d3a0dc2020-12-02 00:33:42 +0000517 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000518 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000519 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000520 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
521 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530522 if dh.pOnuTP == nil {
523 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000524 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530525 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000526 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530527 }
528
529 msgBody := msg.GetBody()
530 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
531 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000532 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530533 "device-id": dh.deviceID, "error": err})
534 return err
535 }
536
537 //compare TECH_PROFILE_DOWNLOAD_REQUEST
538 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000539 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000540
541 if delTcontMsg.UniId > 255 {
542 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
543 delTcontMsg.UniId, dh.deviceID))
544 }
545 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700546 tpPath := delTcontMsg.TpInstancePath
Girish Gowdra041dcb32020-11-16 16:54:30 -0800547 tpID, err := GetTpIDFromTpPath(tpPath)
548 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000549 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800550 return err
551 }
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700552 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID, "tcont": delTcontMsg.AllocId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000553
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700554 pDevEntry.freeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530555
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700556 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
557 cResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000558
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700559}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000560
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700561func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
562 uniID uint8, tpID uint8, pathString string, resource resourceEntry, entryID uint32) error {
563 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
564 if pDevEntry == nil {
565 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
566 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530567 }
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700568 var resourceName string
569 if cResourceGemPort == resource {
570 resourceName = "Gem"
571 } else {
572 resourceName = "Tcont"
573 }
574
575 // deadline context to ensure completion of background routines waited for
576 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
577 dctx, cancel := context.WithDeadline(context.Background(), deadline)
578
579 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
580
581 var wg sync.WaitGroup
582 wg.Add(1) // for the 1 go routine to finish
583 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
584 resource, entryID, &wg)
585 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
586 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); err != nil {
587 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
588 return err
589 }
590
591 if dh.pOnuTP.isTechProfileConfigCleared(ctx, uniID, tpID) {
592 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID})
593 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
594 pDevEntry.resetKvProcessingErrorIndication()
595 var wg2 sync.WaitGroup
596 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
597 wg2.Add(1)
598 // Removal of the gem id mapping represents the removal of the tech profile
599 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID})
600 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
601 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
602 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
603 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
604 return err
605 }
606 }
607 }
608 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.deviceID,
609 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530610 return nil
611}
612
Himani Chawla6d2ae152020-09-02 13:11:20 +0530613//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000614// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
615// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000616func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000617 msgID := msg.Header.Id
618 msgType := msg.Header.Type
619 fromTopic := msg.Header.FromTopic
620 toTopic := msg.Header.ToTopic
621 toDeviceID := msg.Header.ToDeviceId
622 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000623 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000624 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
625
626 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000627 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000628 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
629 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000630 {
mpagenko057889c2021-01-21 16:51:58 +0000631 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000632 }
mpagenkoaf801632020-07-03 10:00:42 +0000633 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
634 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000635 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000636 }
637 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
638 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000639 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000640
mpagenkoaf801632020-07-03 10:00:42 +0000641 }
642 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
643 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000644 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000645 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000646 default:
647 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000648 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000649 "msgType": msg.Header.Type, "device-id": dh.deviceID})
650 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000651 }
652 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000653}
654
mpagenkodff5dda2020-08-28 11:52:01 +0000655//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000656func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
657 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000658 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
ozgecanetsia82b91a62021-05-21 18:54:49 +0300659 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID, "metadata": apFlowMetaData})
mpagenko01e726e2020-10-23 09:45:29 +0000660 var retError error = nil
661 //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 +0000662 if apOfFlowChanges.ToRemove != nil {
663 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000664 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000665 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000666 "device-id": dh.deviceID})
667 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000668 continue
669 }
670 flowInPort := flow.GetInPort(flowItem)
671 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000672 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 +0000673 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
674 continue
675 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000676 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000677 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000678 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000679 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000680 continue
681 } else {
682 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530683 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000684 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
685 loUniPort = uniPort
686 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000687 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000688 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
689 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
690 flowInPort, dh.deviceID)
691 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000692 }
693 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000694 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000695 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000696 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000697 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000698 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000699 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000700 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000701 log.Fields{"device-id": dh.deviceID, "error": err})
702 retError = err
703 continue
704 //return err
705 } else { // if last setting succeeds, overwrite possibly previously set error
706 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000707 }
708 }
709 }
710 }
mpagenko01e726e2020-10-23 09:45:29 +0000711 if apOfFlowChanges.ToAdd != nil {
712 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
713 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000714 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000715 "device-id": dh.deviceID})
716 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
717 continue
718 }
719 flowInPort := flow.GetInPort(flowItem)
720 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000721 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 +0000722 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
723 continue
724 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
725 } else if flowInPort == dh.ponPortNumber {
726 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000728 "device-id": dh.deviceID, "inPort": flowInPort})
729 continue
730 } else {
731 // this is the relevant upstream flow
732 var loUniPort *onuUniPort
733 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
734 loUniPort = uniPort
735 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000736 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000737 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
738 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
739 flowInPort, dh.deviceID)
740 continue
741 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
742 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000743 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
744 // if not, we just throw some error here to have an indication about that, if we really need to support that
745 // then we would need to create some means to activate the internal stored flows
746 // after the device gets active automatically (and still with its dependency to the TechProfile)
747 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
748 // also abort for the other still possible flows here
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000749 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000750 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000751 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000752 return fmt.Errorf("improper device state on device %s", dh.deviceID)
753 }
754
mpagenko01e726e2020-10-23 09:45:29 +0000755 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000756 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000757 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
758 "uniPortName": loUniPort.name})
ozgecanetsia82b91a62021-05-21 18:54:49 +0300759 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort, apFlowMetaData)
mpagenko01e726e2020-10-23 09:45:29 +0000760 //try next flow after processing error
761 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000762 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000763 log.Fields{"device-id": dh.deviceID, "error": err})
764 retError = err
765 continue
766 //return err
767 } else { // if last setting succeeds, overwrite possibly previously set error
768 retError = nil
769 }
770 }
771 }
772 }
773 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000774}
775
Himani Chawla6d2ae152020-09-02 13:11:20 +0530776//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000777//following are the expected device states after this activity:
778//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
779// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000780func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
781 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000782
mpagenko900ee4b2020-10-12 11:56:34 +0000783 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000784 //note that disableDevice sequences in some 'ONU active' state may yield also
785 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000786 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000787 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000788 //disable-device shall be just a UNi/ONU-G related admin state setting
789 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000790
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000791 if dh.isReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000792 // disable UNI ports/ONU
793 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
794 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000795 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000796 } else { //LockStateFSM already init
797 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000798 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000799 }
800 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000801 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000802 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000803 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000804 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
805 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000806 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000807 }
mpagenko01e726e2020-10-23 09:45:29 +0000808 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000809
810 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000811 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000812 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300813 }
814}
815
Himani Chawla6d2ae152020-09-02 13:11:20 +0530816//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000817func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
818 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000819
mpagenkoaa3afe92021-05-21 16:20:58 +0000820 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000821 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
822 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
823 // for real ONU's that should have nearly no influence
824 // Note that for real ONU's there is anyway a problematic situation with following sequence:
825 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
826 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
827 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000828 dh.setReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000829
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000830 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000831 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000832 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000833 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000834 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000835 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000836 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000837 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300838}
839
dbainbri4d3a0dc2020-12-02 00:33:42 +0000840func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
841 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000842
dbainbri4d3a0dc2020-12-02 00:33:42 +0000843 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000844 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000845 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000846 return
847 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000848 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000849 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000850 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000851 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000852 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000853 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700854 dh.stopReconciling(ctx, false)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000855 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000856 }
Himani Chawla4d908332020-08-31 12:30:20 +0530857 var onuIndication oop.OnuIndication
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000858 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000859 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
860 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
861 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
862 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000863 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000864 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000865}
866
dbainbri4d3a0dc2020-12-02 00:33:42 +0000867func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
868 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000869
dbainbri4d3a0dc2020-12-02 00:33:42 +0000870 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000871 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000872 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000873 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700874 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000875 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000876 return
877 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000878 dh.pOnuTP.lockTpProcMutex()
879 defer dh.pOnuTP.unlockTpProcMutex()
880
mpagenko5dc85a02021-08-02 12:35:01 +0000881 pDevEntry.mutexPersOnuConfig.RLock()
882 persMutexLock := true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000883 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko5dc85a02021-08-02 12:35:01 +0000884 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000885 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000886 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000887 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700888 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000889 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000890 return
891 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000892 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700893 techProfsFound := false
894 techProfInstLoadFailed := false
895outerLoop:
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000896 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000897 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
898 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000899 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000900 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000901 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000902 }
mpagenko5dc85a02021-08-02 12:35:01 +0000903 //release mutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
904 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
905 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
906 pDevEntry.mutexPersOnuConfig.RUnlock()
907 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700908 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800909 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700910 // Request the TpInstance again from the openolt adapter in case of reconcile
911 iaTechTpInst, err := dh.AdapterProxy.TechProfileInstanceRequest(ctx, uniData.PersTpPathMap[tpID],
912 dh.device.ParentPortNo, dh.device.ProxyAddress.OnuId, uint32(uniData.PersUniID),
913 dh.pOpenOnuAc.config.Topic, dh.ProxyAddressType,
914 dh.parentID, dh.ProxyAddressID)
915 if err != nil || iaTechTpInst == nil {
916 logger.Errorw(ctx, "error fetching tp instance",
917 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID, "err": err})
918 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
919 break outerLoop
920 }
921 var tpInst tech_profile.TechProfileInstance
922 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
923 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
924 tpInst = *techTpInst.TpInstance
mpagenko5dc85a02021-08-02 12:35:01 +0000925 logger.Debugw(ctx, "received-tp-instance-successfully-after-reconcile", log.Fields{
926 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700927 default: // do not support epon or other tech
mpagenko5dc85a02021-08-02 12:35:01 +0000928 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
929 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700930 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
931 break outerLoop
932 }
933
Girish Gowdra041dcb32020-11-16 16:54:30 -0800934 // deadline context to ensure completion of background routines waited for
935 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
936 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000937 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000938
Girish Gowdra041dcb32020-11-16 16:54:30 -0800939 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
940 var wg sync.WaitGroup
941 wg.Add(1) // for the 1 go routine to finish
Girish Gowdra50e56422021-06-01 16:46:04 -0700942 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000943 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800944 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000945 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700946 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
947 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800948 }
mpagenko5dc85a02021-08-02 12:35:01 +0000949 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000950 if len(uniData.PersFlowParams) != 0 {
951 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000952 }
mpagenko5dc85a02021-08-02 12:35:01 +0000953 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
954 persMutexLock = true
955 } // for all UNI entries from sOnuPersistentData
956 if persMutexLock { // if loop was left with mutexPersOnuConfig still set
957 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000958 }
mpagenko5dc85a02021-08-02 12:35:01 +0000959
960 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
961 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
962}
963
964func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
965 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
966 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000967 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
968 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 Hildebrandtbe523842021-03-10 10:47:18 +0000972 return
973 }
mpagenko5dc85a02021-08-02 12:35:01 +0000974 if abTechProfInstLoadFailed {
Girish Gowdra50e56422021-06-01 16:46:04 -0700975 dh.setDeviceReason(drTechProfileConfigDownloadFailed)
976 dh.stopReconciling(ctx, false)
977 return
978 } else if dh.isSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000979 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
980 }
mpagenko5dc85a02021-08-02 12:35:01 +0000981 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000982 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
983 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000984 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700985 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000986 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000987 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000988}
989
dbainbri4d3a0dc2020-12-02 00:33:42 +0000990func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
991 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000992
dbainbri4d3a0dc2020-12-02 00:33:42 +0000993 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000994 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000995 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000996 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700997 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000998 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000999 return
1000 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001001
mpagenko5dc85a02021-08-02 12:35:01 +00001002 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001003 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko5dc85a02021-08-02 12:35:01 +00001004 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001005 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001006 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001007 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001008 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001009 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001010 return
1011 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001012 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001013 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001014 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1015 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001016 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001017 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001018 continue
1019 }
1020 if len(uniData.PersTpPathMap) == 0 {
1021 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
1022 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001023 // It doesn't make sense to configure any flows if no TPs are available
1024 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001025 }
mpagenko5dc85a02021-08-02 12:35:01 +00001026 //release mutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1027 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
1028 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1029 pDevEntry.mutexPersOnuConfig.RUnlock()
1030
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001031 var uniPort *onuUniPort
1032 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +00001033 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001034 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001035 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
1036 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001037 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001038 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001039 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001040 return
1041 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001042 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001043 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001044 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001045 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001046 for _, flowData := range uniData.PersFlowParams {
mpagenko5dc85a02021-08-02 12:35:01 +00001047 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1048 "device-id": dh.deviceID, "uni-id": uniData.PersUniID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001049 // If this is the last flow for the device we need to announce it the waiting
1050 // chReconcilingFlowsFinished channel
1051 if flowsProcessed == len(uniData.PersFlowParams)-1 {
1052 lastFlowToReconcile = true
1053 }
mpagenko01e726e2020-10-23 09:45:29 +00001054 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenko37047052021-07-27 10:01:29 +00001055 dh.lockVlanConfig.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001056 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001057 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +00001058 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +03001059 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001060 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001061 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001062 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001063 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00001064 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +03001065 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001066 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001067 }
1068 }
mpagenko37047052021-07-27 10:01:29 +00001069 dh.lockVlanConfig.Unlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001070 flowsProcessed++
mpagenko5dc85a02021-08-02 12:35:01 +00001071 } //for all flows of this UNI
1072 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
1073 "device-id": dh.deviceID, "uni-id": uniData.PersUniID, "flowsProcessed": flowsProcessed,
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001074 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
1075 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001076 // this can't be used as global finished reconciling flag because
1077 // assumes is getting called before the state machines for the last flow is completed,
1078 // while this is not guaranteed.
1079 //dh.setReconcilingFlows(false)
mpagenko5dc85a02021-08-02 12:35:01 +00001080 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
1081 } // for all UNI entries from sOnuPersistentData
1082 pDevEntry.mutexPersOnuConfig.RUnlock()
1083
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001084 if !flowsFound {
1085 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
1086 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001087 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001088 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001089 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001090 return
1091 }
1092 if dh.isSkipOnuConfigReconciling() {
1093 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001094 }
1095}
1096
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001097func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
1098 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001099 dh.stopReconciling(ctx, true)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001100}
1101
dbainbri4d3a0dc2020-12-02 00:33:42 +00001102func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
1103 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001104
dbainbri4d3a0dc2020-12-02 00:33:42 +00001105 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001106 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001107 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +00001108 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001109 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001110 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001111
1112 // deadline context to ensure completion of background routines waited for
1113 //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 +05301114 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001115 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001116
1117 pDevEntry.resetKvProcessingErrorIndication()
1118
1119 var wg sync.WaitGroup
1120 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001121 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1122 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001123
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001124 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001125 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001126}
1127
mpagenko15ff4a52021-03-02 10:09:20 +00001128//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1129// before this change here return like this was used:
1130// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1131//was and is called in background - error return does not make sense
1132func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1133 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1134 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001135 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001136 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001137 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001138 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301139 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001140 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001141 return
Himani Chawla4d908332020-08-31 12:30:20 +05301142 }
mpagenko01e726e2020-10-23 09:45:29 +00001143
1144 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001145 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001146
dbainbri4d3a0dc2020-12-02 00:33:42 +00001147 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001148 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001149 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001150 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001151 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001152 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001153 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001154 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001155 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001156 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001157 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001158 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001159 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1160 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1161 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1162 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001163}
1164
mpagenkoc8bba412021-01-15 15:38:44 +00001165//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +00001166func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1167 apDownloadManager *adapterDownloadManager) error {
1168 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001169 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001170
1171 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001172 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1173 if pDevEntry == nil {
1174 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1175 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1176 }
1177
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001178 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001179 var inactiveImageID uint16
1180 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1181 dh.lockUpgradeFsm.Lock()
1182 defer dh.lockUpgradeFsm.Unlock()
1183 if dh.pOnuUpradeFsm == nil {
1184 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1185 if err == nil {
1186 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1187 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1188 "device-id": dh.deviceID, "error": err})
1189 }
1190 } else {
1191 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001192 "device-id": dh.deviceID, "error": err})
1193 }
mpagenko15ff4a52021-03-02 10:09:20 +00001194 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1195 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1196 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1197 if pUpgradeStatemachine != nil {
1198 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1199 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1200 "device-id": dh.deviceID, "error": err})
1201 }
1202 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1203 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1204 // for now a second start of download should work again
1205 } else { //should never occur
1206 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1207 "device-id": dh.deviceID})
1208 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001209 }
mpagenko80622a52021-02-09 16:53:23 +00001210 }
mpagenko15ff4a52021-03-02 10:09:20 +00001211 } else {
1212 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1213 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001214 }
1215 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001216 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1217 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001218 }
1219 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001220}
1221
mpagenkoc26d4c02021-05-06 14:27:57 +00001222//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1223// after the OnuImage has been downloaded to the adapter, called in background
1224func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
1225 apDownloadManager *fileDownloadManager, aImageIdentifier string) {
1226
1227 var err error
1228 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1229 if pDevEntry == nil {
1230 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1231 return
1232 }
1233
1234 var inactiveImageID uint16
1235 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1236 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
1237 "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
1238 dh.lockUpgradeFsm.Lock()
1239 defer dh.lockUpgradeFsm.Unlock()
1240 if dh.pOnuUpradeFsm == nil {
1241 //OmciOnuSwUpgradeDone could be used to create some Kafka event with information on upgrade completion,
1242 // but none yet defined
1243 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1244 if err == nil {
1245 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
Holger Hildebrandtac010732021-06-02 13:35:39 +00001246 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00001247 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1248 "device-id": dh.deviceID, "error": err})
1249 return
1250 }
1251 } else {
1252 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1253 "device-id": dh.deviceID, "error": err})
1254 }
1255 return
1256 }
1257 //OnuSw upgrade already running - restart (with possible abort of running)
1258 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1259 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1260 if pUpgradeStatemachine != nil {
1261 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1262 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1263 "device-id": dh.deviceID, "error": err})
1264 return
1265 }
1266 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1267 // for now a second start of download should work again - must still be initiated by user
1268 } else { //should never occur
1269 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1270 "device-id": dh.deviceID})
1271 }
1272 return
1273 }
1274 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1275 "device-id": dh.deviceID, "error": err})
1276}
1277
1278//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001279func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1280 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001281 var err error
1282 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1283 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1284 // 2.) activation of the inactive image
1285
1286 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1287 if pDevEntry == nil {
1288 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001289 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001290 }
1291 dh.lockUpgradeFsm.RLock()
1292 if dh.pOnuUpradeFsm != nil {
1293 dh.lockUpgradeFsm.RUnlock()
1294 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1295 dh.deviceID, dh.deviceID)
1296 if getErr != nil || onuVolthaDevice == nil {
1297 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 +00001298 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001299 }
1300 // use the OnuVendor identification from this device for the internal unique name
1301 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1302 // 1.) check a started upgrade process and rely the activation request to it
1303 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001304 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001305 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1306 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001307 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001308 }
mpagenko183647c2021-06-08 15:25:04 +00001309 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1310 "device-id": dh.deviceID, "image-id": imageIdentifier})
1311 var pImageStates *voltha.ImageState
1312 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1313 pImageStates = &voltha.ImageState{}
1314 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1315 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1316 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1317 }
1318 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001319 } //else
1320 dh.lockUpgradeFsm.RUnlock()
1321
1322 // 2.) check if requested image-version equals the inactive one and start its activation
1323 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1324 var inactiveImageID uint16
1325 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1326 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1327 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
mpagenko183647c2021-06-08 15:25:04 +00001328 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001329 }
1330 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1331 if err == nil {
1332 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1333 inactiveImageID, aCommitRequest); err != nil {
1334 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1335 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001336 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001337 }
1338 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1339 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001340 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 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1350 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001351 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001352}
1353
1354//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001355func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1356 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001357 var err error
1358 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1359 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1360 // 2.) commitment of the active image
1361
1362 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1363 if pDevEntry == nil {
1364 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001365 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001366 }
1367 dh.lockUpgradeFsm.RLock()
1368 if dh.pOnuUpradeFsm != nil {
1369 dh.lockUpgradeFsm.RUnlock()
1370 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1371 dh.deviceID, dh.deviceID)
1372 if getErr != nil || onuVolthaDevice == nil {
1373 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 +00001374 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001375 }
1376 // use the OnuVendor identification from this device for the internal unique name
1377 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1378 // 1.) check a started upgrade process and rely the commitment request to it
1379 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001380 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001381 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1382 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001383 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001384 }
mpagenko183647c2021-06-08 15:25:04 +00001385 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1386 "device-id": dh.deviceID, "image-id": imageIdentifier})
1387 var pImageStates *voltha.ImageState
1388 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1389 pImageStates := &voltha.ImageState{}
1390 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1391 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1392 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1393 }
1394 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001395 } //else
1396 dh.lockUpgradeFsm.RUnlock()
1397
mpagenko183647c2021-06-08 15:25:04 +00001398 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001399 var activeImageID uint16
1400 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1401 logger.Errorw(ctx, "get active image failed", log.Fields{
1402 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
mpagenko183647c2021-06-08 15:25:04 +00001403 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001404 }
1405 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1406 if err == nil {
1407 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1408 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1409 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001410 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001411 }
1412 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1413 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001414 var pImageStates *voltha.ImageState
1415 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1416 pImageStates := &voltha.ImageState{}
1417 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1418 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1419 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1420 }
1421 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001422 } //else
1423 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1424 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001425 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001426}
1427
mpagenkoaa3afe92021-05-21 16:20:58 +00001428func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
1429 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1430 pDeviceImageState.DeviceId = dh.deviceID
mpagenko183647c2021-06-08 15:25:04 +00001431 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001432 dh.lockUpgradeFsm.RLock()
1433 if dh.pOnuUpradeFsm != nil {
1434 dh.lockUpgradeFsm.RUnlock()
mpagenko183647c2021-06-08 15:25:04 +00001435 if pImageStates, err := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion); err == nil {
mpagenkoaa3afe92021-05-21 16:20:58 +00001436 pDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
1437 pDeviceImageState.ImageState.Reason = pImageStates.Reason
1438 pDeviceImageState.ImageState.ImageState = pImageStates.ImageState
1439 } else {
1440 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1441 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1442 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1443 }
1444 } else {
1445 dh.lockUpgradeFsm.RUnlock()
1446 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1447 if dh.upgradeSuccess {
1448 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
1449 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMITTED
1450 } else {
1451 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1452 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1453 }
1454 }
1455}
1456
1457func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1458 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1459 pDeviceImageState.DeviceId = dh.deviceID
mpagenko7455fd42021-06-10 16:25:55 +00001460 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001461 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1462 dh.lockUpgradeFsm.RLock()
1463 if dh.pOnuUpradeFsm != nil {
1464 dh.lockUpgradeFsm.RUnlock()
1465 //option: it could be also checked if the upgrade FSM is running on the given imageIdentifier or version
1466 // by now just straightforward assume this to be true
1467 dh.pOnuUpradeFsm.CancelProcessing(ctx)
1468 //nolint:misspell
1469 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
1470 //nolint:misspell
1471 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1472 } else {
1473 dh.lockUpgradeFsm.RUnlock()
1474 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1475 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1476 }
1477}
1478
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001479func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1480
1481 var onuImageStatus *OnuImageStatus
1482
1483 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1484 if pDevEntry != nil {
1485 onuImageStatus = NewOnuImageStatus(pDevEntry)
1486 pDevEntry.mutexOnuImageStatus.Lock()
1487 pDevEntry.pOnuImageStatus = onuImageStatus
1488 pDevEntry.mutexOnuImageStatus.Unlock()
1489
1490 } else {
1491 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1492 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1493 }
1494 images, err := onuImageStatus.getOnuImageStatus(ctx)
1495 pDevEntry.mutexOnuImageStatus.Lock()
1496 pDevEntry.pOnuImageStatus = nil
1497 pDevEntry.mutexOnuImageStatus.Unlock()
1498 return images, err
1499}
1500
Himani Chawla6d2ae152020-09-02 13:11:20 +05301501// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001502// #####################################################################################
1503
1504// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301505// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001506
dbainbri4d3a0dc2020-12-02 00:33:42 +00001507func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1508 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 +00001509}
1510
1511// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001512func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001513
dbainbri4d3a0dc2020-12-02 00:33:42 +00001514 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001515 var err error
1516
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001517 // populate what we know. rest comes later after mib sync
1518 dh.device.Root = false
1519 dh.device.Vendor = "OpenONU"
1520 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001521 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001522 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001523
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001524 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001525
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001526 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001527 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1528 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301529 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001530 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001531 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001532 log.Fields{"device-id": dh.deviceID})
1533 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001534
Himani Chawla4d908332020-08-31 12:30:20 +05301535 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001536 dh.ponPortNumber = dh.device.ParentPortNo
1537
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001538 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1539 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1540 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001541 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001542 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301543 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001544
1545 /*
1546 self._pon = PonPort.create(self, self._pon_port_number)
1547 self._pon.add_peer(self.parent_id, self._pon_port_number)
1548 self.logger.debug('adding-pon-port-to-agent',
1549 type=self._pon.get_port().type,
1550 admin_state=self._pon.get_port().admin_state,
1551 oper_status=self._pon.get_port().oper_status,
1552 )
1553 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001554 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001555 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001556 var ponPortNo uint32 = 1
1557 if dh.ponPortNumber != 0 {
1558 ponPortNo = dh.ponPortNumber
1559 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001560
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001561 pPonPort := &voltha.Port{
1562 PortNo: ponPortNo,
1563 Label: fmt.Sprintf("pon-%d", ponPortNo),
1564 Type: voltha.Port_PON_ONU,
1565 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301566 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001567 PortNo: ponPortNo}}, // Peer port is parent's port number
1568 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001569 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1570 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001571 e.Cancel(err)
1572 return
1573 }
1574 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001575 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001576 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001577 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001578}
1579
1580// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001581func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001582
dbainbri4d3a0dc2020-12-02 00:33:42 +00001583 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001584 var err error
1585 /*
1586 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1587 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1588 return nil
1589 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001590 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1591 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001592 e.Cancel(err)
1593 return
1594 }
1595
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001596 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001597 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001598 // reconcilement will be continued after mib download is done
1599 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001600
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001601 /*
1602 ############################################################################
1603 # Setup Alarm handler
1604 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1605 device.serial_number)
1606 ############################################################################
1607 # Setup PM configuration for this device
1608 # Pass in ONU specific options
1609 kwargs = {
1610 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1611 'heartbeat': self.heartbeat,
1612 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1613 }
1614 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1615 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1616 self.logical_device_id, device.serial_number,
1617 grouped=True, freq_override=False, **kwargs)
1618 pm_config = self._pm_metrics.make_proto()
1619 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1620 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1621 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1622
1623 # Note, ONU ID and UNI intf set in add_uni_port method
1624 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1625 ani_ports=[self._pon])
1626
1627 # Code to Run OMCI Test Action
1628 kwargs_omci_test_action = {
1629 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1630 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1631 }
1632 serial_number = device.serial_number
1633 self._test_request = OmciTestRequest(self.core_proxy,
1634 self.omci_agent, self.device_id,
1635 AniG, serial_number,
1636 self.logical_device_id,
1637 exclusive=False,
1638 **kwargs_omci_test_action)
1639
1640 self.enabled = True
1641 else:
1642 self.logger.info('onu-already-activated')
1643 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001644
dbainbri4d3a0dc2020-12-02 00:33:42 +00001645 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001646}
1647
1648// doStateConnected get the device info and update to voltha core
1649// for comparison of the original method (not that easy to uncomment): compare here:
1650// voltha-openolt-adapter/adaptercore/device_handler.go
1651// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001652func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001653
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301655 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001656 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001657 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001658}
1659
1660// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001661func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001662
dbainbri4d3a0dc2020-12-02 00:33:42 +00001663 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301664 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001665 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001666 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001667
1668 /*
1669 // Synchronous call to update device state - this method is run in its own go routine
1670 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1671 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001672 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 +00001673 return err
1674 }
1675 return nil
1676 */
1677}
1678
1679// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001680func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001681
dbainbri4d3a0dc2020-12-02 00:33:42 +00001682 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001683 var err error
1684
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001685 device := dh.device
1686 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001687 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001688 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001689 e.Cancel(err)
1690 return
1691 }
1692
1693 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001694 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001695 /*
1696 // Update the all ports state on that device to disable
1697 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001698 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001699 return er
1700 }
1701
1702 //Update the device oper state and connection status
1703 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1704 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1705 dh.device = cloned
1706
1707 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001708 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001709 return er
1710 }
1711
1712 //get the child device for the parent device
1713 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1714 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001715 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001716 return err
1717 }
1718 for _, onuDevice := range onuDevices.Items {
1719
1720 // Update onu state as down in onu adapter
1721 onuInd := oop.OnuIndication{}
1722 onuInd.OperState = "down"
1723 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1724 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1725 if er != nil {
1726 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001727 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001728 //Do not return here and continue to process other ONUs
1729 }
1730 }
1731 // * Discovered ONUs entries need to be cleared , since after OLT
1732 // is up, it starts sending discovery indications again* /
1733 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001734 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001735 return nil
1736 */
Himani Chawla4d908332020-08-31 12:30:20 +05301737 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001738 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001739 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001740}
1741
Himani Chawla6d2ae152020-09-02 13:11:20 +05301742// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001743// #################################################################################
1744
1745// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301746// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001747
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001748//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001749func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001750 dh.lockDevice.RLock()
1751 pOnuDeviceEntry := dh.pOnuOmciDevice
1752 if aWait && pOnuDeviceEntry == nil {
1753 //keep the read sema short to allow for subsequent write
1754 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001755 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001756 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1757 // so it might be needed to wait here for that event with some timeout
1758 select {
1759 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001760 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001761 return nil
1762 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001763 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001764 // if written now, we can return the written value without sema
1765 return dh.pOnuOmciDevice
1766 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001767 }
mpagenko3af1f032020-06-10 08:53:41 +00001768 dh.lockDevice.RUnlock()
1769 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001770}
1771
Himani Chawla6d2ae152020-09-02 13:11:20 +05301772//setOnuDeviceEntry sets the ONU device entry within the handler
1773func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001774 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001775 dh.lockDevice.Lock()
1776 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001777 dh.pOnuOmciDevice = apDeviceEntry
1778 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001779 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301780 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001781 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001782}
1783
Himani Chawla6d2ae152020-09-02 13:11:20 +05301784//addOnuDeviceEntry creates a new ONU device or returns the existing
1785func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001786 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001787
dbainbri4d3a0dc2020-12-02 00:33:42 +00001788 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001789 if deviceEntry == nil {
1790 /* costum_me_map in python code seems always to be None,
1791 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1792 /* also no 'clock' argument - usage open ...*/
1793 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001794 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001795 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001796 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301797 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001798 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001799 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001800 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001801 // fire deviceEntry ready event to spread to possibly waiting processing
1802 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001803 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001804 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001805 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001806 }
1807 // might be updated with some error handling !!!
1808 return nil
1809}
1810
dbainbri4d3a0dc2020-12-02 00:33:42 +00001811func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1812 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001813 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1814
1815 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001816
dbainbri4d3a0dc2020-12-02 00:33:42 +00001817 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001818 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001819 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001820 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1821 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001822 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001823 if err := dh.storePersistentData(ctx); err != nil {
1824 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001825 log.Fields{"device-id": dh.deviceID, "err": err})
1826 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001827 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001828 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001829 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001830 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1831 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001832 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001833 }
1834 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001835 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001836 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001837
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001838 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001839 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001840 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001841 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 +00001842 log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001843 dh.stopReconciling(ctx, true)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001844 } else {
1845 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001846 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001847 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001848 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1849 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1850 // 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 +00001851 // 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 +00001852 // so let's just try to keep it simple ...
1853 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001854 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001855 if err != nil || device == nil {
1856 //TODO: needs to handle error scenarios
1857 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1858 return errors.New("Voltha Device not found")
1859 }
1860 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001861
dbainbri4d3a0dc2020-12-02 00:33:42 +00001862 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001863 return err
mpagenko3af1f032020-06-10 08:53:41 +00001864 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001865
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001866 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001867
1868 /* this might be a good time for Omci Verify message? */
1869 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001870 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001871 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001872 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001873 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001874
1875 /* give the handler some time here to wait for the OMCi verification result
1876 after Timeout start and try MibUpload FSM anyway
1877 (to prevent stopping on just not supported OMCI verification from ONU) */
1878 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001879 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001880 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001881 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001882 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001883 }
1884
1885 /* In py code it looks earlier (on activate ..)
1886 # Code to Run OMCI Test Action
1887 kwargs_omci_test_action = {
1888 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1889 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1890 }
1891 serial_number = device.serial_number
1892 self._test_request = OmciTestRequest(self.core_proxy,
1893 self.omci_agent, self.device_id,
1894 AniG, serial_number,
1895 self.logical_device_id,
1896 exclusive=False,
1897 **kwargs_omci_test_action)
1898 ...
1899 # Start test requests after a brief pause
1900 if not self._test_request_started:
1901 self._test_request_started = True
1902 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1903 reactor.callLater(tststart, self._test_request.start_collector)
1904
1905 */
1906 /* which is then: in omci_test_request.py : */
1907 /*
1908 def start_collector(self, callback=None):
1909 """
1910 Start the collection loop for an adapter if the frequency > 0
1911
1912 :param callback: (callable) Function to call to collect PM data
1913 """
1914 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1915 if callback is None:
1916 callback = self.perform_test_omci
1917
1918 if self.lc is None:
1919 self.lc = LoopingCall(callback)
1920
1921 if self.default_freq > 0:
1922 self.lc.start(interval=self.default_freq / 10)
1923
1924 def perform_test_omci(self):
1925 """
1926 Perform the initial test request
1927 """
1928 ani_g_entities = self._device.configuration.ani_g_entities
1929 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1930 is not None else None
1931 self._entity_id = ani_g_entities_ids[0]
1932 self.logger.info('perform-test', entity_class=self._entity_class,
1933 entity_id=self._entity_id)
1934 try:
1935 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1936 result = yield self._device.omci_cc.send(frame)
1937 if not result.fields['omci_message'].fields['success_code']:
1938 self.logger.info('Self-Test Submitted Successfully',
1939 code=result.fields[
1940 'omci_message'].fields['success_code'])
1941 else:
1942 raise TestFailure('Test Failure: {}'.format(
1943 result.fields['omci_message'].fields['success_code']))
1944 except TimeoutError as e:
1945 self.deferred.errback(failure.Failure(e))
1946
1947 except Exception as e:
1948 self.logger.exception('perform-test-Error', e=e,
1949 class_id=self._entity_class,
1950 entity_id=self._entity_id)
1951 self.deferred.errback(failure.Failure(e))
1952
1953 */
1954
1955 // PM related heartbeat??? !!!TODO....
1956 //self._heartbeat.enabled = True
1957
mpagenko1cc3cb42020-07-27 15:24:38 +00001958 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1959 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1960 * 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 +05301961 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001962 */
1963 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001964 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001965 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001966 if pMibUlFsm.Is(ulStDisabled) {
1967 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001968 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 +00001969 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301970 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001971 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301972 //Determine ONU status and start/re-start MIB Synchronization tasks
1973 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001974 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301975 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001976 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 +00001977 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001978 }
Himani Chawla4d908332020-08-31 12:30:20 +05301979 } else {
1980 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001981 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 +00001982 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301983 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001984 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001985 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001986 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001987 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001988 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001989 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001990 }
1991 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001992 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001993 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001994 }
1995 return nil
1996}
1997
dbainbri4d3a0dc2020-12-02 00:33:42 +00001998func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001999 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002000 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002001 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002002 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002003
mpagenko900ee4b2020-10-12 11:56:34 +00002004 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2005 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2006 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002007 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002008 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00002009 log.Fields{"device-id": dh.deviceID, "error": err})
2010 // abort: system behavior is just unstable ...
2011 return err
2012 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002013 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002014 _ = 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 +00002015
2016 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
2017 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
2018 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00002019 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002020 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002021 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002022 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002023 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002024 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002025
2026 //TODO!!! remove existing traffic profiles
2027 /* from py code, if TP's exist, remove them - not yet implemented
2028 self._tp = dict()
2029 # Let TP download happen again
2030 for uni_id in self._tp_service_specific_task:
2031 self._tp_service_specific_task[uni_id].clear()
2032 for uni_id in self._tech_profile_download_done:
2033 self._tech_profile_download_done[uni_id].clear()
2034 */
2035
dbainbri4d3a0dc2020-12-02 00:33:42 +00002036 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002037
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002038 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002039
dbainbri4d3a0dc2020-12-02 00:33:42 +00002040 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002041 // abort: system behavior is just unstable ...
2042 return err
2043 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002044 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002045 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002046 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00002047 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002048 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002049 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00002050 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002051 // abort: system behavior is just unstable ...
2052 return err
2053 }
2054 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002055 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002056 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002057 return nil
2058}
2059
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002060func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002061 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2062 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2063 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2064 // and using the stop/reset event should never harm
2065
dbainbri4d3a0dc2020-12-02 00:33:42 +00002066 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002067 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002068 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002069 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2070 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002071 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002072 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002073 }
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002074 pDevEntry.mutexOnuImageStatus.RLock()
2075 if pDevEntry.pOnuImageStatus != nil {
2076 pDevEntry.pOnuImageStatus.CancelProcessing(ctx)
2077 }
2078 pDevEntry.mutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002079
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002080 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002081 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002082 }
2083 //MibDownload may run
2084 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2085 if pMibDlFsm != nil {
2086 _ = pMibDlFsm.Event(dlEvReset)
2087 }
2088 //port lock/unlock FSM's may be active
2089 if dh.pUnlockStateFsm != nil {
2090 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2091 }
2092 if dh.pLockStateFsm != nil {
2093 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2094 }
2095 //techProfile related PonAniConfigFsm FSM may be active
2096 if dh.pOnuTP != nil {
2097 // should always be the case here
2098 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
2099 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08002100 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00002101 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002102 }
mpagenko900ee4b2020-10-12 11:56:34 +00002103 }
2104 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002105 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002106 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00002107 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
2108 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002109 dh.lockVlanConfig.RUnlock()
2110 //reset of all Fsm is always accompanied by global persistency data removal
2111 // no need to remove specific data
2112 pVlanFilterFsm.RequestClearPersistency(false)
2113 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002114 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002115 } else {
2116 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002117 }
2118 }
2119 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002120 if dh.getCollectorIsRunning() {
2121 // Stop collector routine
2122 dh.stopCollector <- true
2123 }
Himani Chawla1472c682021-03-17 17:11:14 +05302124 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302125 dh.stopAlarmManager <- true
2126 }
2127
mpagenko80622a52021-02-09 16:53:23 +00002128 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00002129 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002130 dh.lockUpgradeFsm.RLock()
2131 if dh.pOnuUpradeFsm != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00002132 dh.pOnuUpradeFsm.CancelProcessing(ctx)
mpagenko80622a52021-02-09 16:53:23 +00002133 }
2134 dh.lockUpgradeFsm.RUnlock()
2135
mpagenko7d6bb022021-03-11 15:07:55 +00002136 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002137 return nil
2138}
2139
dbainbri4d3a0dc2020-12-02 00:33:42 +00002140func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2141 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 +05302142
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002143 // store persistent data collected during MIB upload processing
2144 if err := dh.storePersistentData(ctx); err != nil {
2145 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2146 log.Fields{"device-id": dh.deviceID, "err": err})
2147 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002148 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002149 dh.addAllUniPorts(ctx)
2150
mpagenkoa40e99a2020-11-17 13:50:39 +00002151 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2152 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2153 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2154 * disable/enable toggling here to allow traffic
2155 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2156 * like the py comment says:
2157 * # start by locking all the unis till mib sync and initial mib is downloaded
2158 * # this way we can capture the port down/up events when we are ready
2159 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302160
mpagenkoa40e99a2020-11-17 13:50:39 +00002161 // Init Uni Ports to Admin locked state
2162 // *** should generate UniLockStateDone event *****
2163 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002164 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002165 } else { //LockStateFSM already init
2166 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002167 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002168 }
2169}
2170
dbainbri4d3a0dc2020-12-02 00:33:42 +00002171func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2172 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302173 /* Mib download procedure -
2174 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2175 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002176 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002177 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002178 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002179 return
2180 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302181 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2182 if pMibDlFsm != nil {
2183 if pMibDlFsm.Is(dlStDisabled) {
2184 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002185 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 +05302186 // maybe try a FSM reset and then again ... - TODO!!!
2187 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002188 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302189 // maybe use more specific states here for the specific download steps ...
2190 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002191 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302192 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002193 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302194 //Begin MIB data download (running autonomously)
2195 }
2196 }
2197 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002198 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002199 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302200 // maybe try a FSM reset and then again ... - TODO!!!
2201 }
2202 /***** Mib download started */
2203 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002204 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302205 }
2206}
2207
dbainbri4d3a0dc2020-12-02 00:33:42 +00002208func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2209 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302210 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002211 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002212 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002213 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002214 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2215 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2216 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2217 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002218 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302219 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
2220 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002221 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302222 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002223 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302224 }
2225 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002226 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302227 log.Fields{"device-id": dh.deviceID})
2228 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002229 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002230
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002231 if !dh.getCollectorIsRunning() {
2232 // Start PM collector routine
2233 go dh.startCollector(ctx)
2234 }
2235 if !dh.getAlarmManagerIsRunning(ctx) {
2236 go dh.startAlarmManager(ctx)
2237 }
2238
Girish Gowdrae0140f02021-02-02 16:55:09 -08002239 // Initialize classical L2 PM Interval Counters
2240 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2241 // There is no way we should be landing here, but if we do then
2242 // there is nothing much we can do about this other than log error
2243 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2244 }
2245
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002246 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002247
2248 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2249 if pDevEntry == nil {
2250 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2251 return
2252 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002253 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002254 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002255 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002256 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2257 log.Fields{"device-id": dh.deviceID})
2258 go dh.reconcileDeviceTechProf(ctx)
2259 // reconcilement will be continued after ani config is done
2260 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002261 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002262 // *** should generate UniUnlockStateDone event *****
2263 if dh.pUnlockStateFsm == nil {
2264 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2265 } else { //UnlockStateFSM already init
2266 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2267 dh.runUniLockFsm(ctx, false)
2268 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302269 }
2270}
2271
dbainbri4d3a0dc2020-12-02 00:33:42 +00002272func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2273 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302274
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002275 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002276 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002277 raisedTs := time.Now().Unix()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002278 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2279 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002280 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002281 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002282 return
2283 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002284 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002285 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002286 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002287 if err := dh.storePersistentData(ctx); err != nil {
2288 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002289 log.Fields{"device-id": dh.deviceID, "err": err})
2290 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302291 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002292 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 +05302293 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002294 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002295 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302296 }
2297}
2298
dbainbri4d3a0dc2020-12-02 00:33:42 +00002299func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2300 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002301 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002302 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00002303 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
2304 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002305 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002306 }
2307
dbainbri4d3a0dc2020-12-02 00:33:42 +00002308 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002309 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002310 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002311
2312 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002313 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002314
dbainbri4d3a0dc2020-12-02 00:33:42 +00002315 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002316 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002317 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002318 return
2319 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002320 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002321 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002322 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002323 if err := dh.storePersistentData(ctx); err != nil {
2324 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002325 log.Fields{"device-id": dh.deviceID, "err": err})
2326 }
mpagenko900ee4b2020-10-12 11:56:34 +00002327}
2328
dbainbri4d3a0dc2020-12-02 00:33:42 +00002329func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2330 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002331 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002332 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002333 voltha.OperStatus_ACTIVE); err != nil {
2334 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002335 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002336 }
2337
dbainbri4d3a0dc2020-12-02 00:33:42 +00002338 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002339 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002340 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002341 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002342
2343 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002344 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002345
dbainbri4d3a0dc2020-12-02 00:33:42 +00002346 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002347 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002348 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002349 return
2350 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002351 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002352 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002353 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002354 if err := dh.storePersistentData(ctx); err != nil {
2355 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002356 log.Fields{"device-id": dh.deviceID, "err": err})
2357 }
mpagenko900ee4b2020-10-12 11:56:34 +00002358}
2359
dbainbri4d3a0dc2020-12-02 00:33:42 +00002360func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002361 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002362 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002363 // attention: the device reason update is done based on ONU-UNI-Port related activity
2364 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002365 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002366 // 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 +00002367 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302368 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002369 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002370 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002371 }
2372 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002373 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002374 // attention: the device reason update is done based on ONU-UNI-Port related activity
2375 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002376 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002377 // 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 +00002378 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002379 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002380 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302381}
2382
dbainbri4d3a0dc2020-12-02 00:33:42 +00002383func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2384 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002385 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302386 // attention: the device reason update is done based on ONU-UNI-Port related activity
2387 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302388
mpagenkof1fc3862021-02-16 10:09:52 +00002389 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002390 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002391 // which may be the case from some previous actvity on another UNI Port of the ONU
2392 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002393 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2394 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002395 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002396 }
2397 }
2398 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002399 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002400 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002401 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002402 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302403 }
mpagenkof1fc3862021-02-16 10:09:52 +00002404
2405 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2406 //events that request KvStore write
2407 if err := dh.storePersistentData(ctx); err != nil {
2408 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2409 log.Fields{"device-id": dh.deviceID, "err": err})
2410 }
2411 } else {
2412 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2413 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002414 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302415}
2416
Himani Chawla6d2ae152020-09-02 13:11:20 +05302417//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002418func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302419 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002420 case MibDatabaseSync:
2421 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002422 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002423 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002424 case UniLockStateDone:
2425 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002426 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002427 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002428 case MibDownloadDone:
2429 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002430 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002431 }
2432 case UniUnlockStateDone:
2433 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002434 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002435 }
mpagenko900ee4b2020-10-12 11:56:34 +00002436 case UniEnableStateDone:
2437 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002438 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002439 }
2440 case UniDisableStateDone:
2441 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002442 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002443 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002444 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002445 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002446 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002447 }
mpagenkof1fc3862021-02-16 10:09:52 +00002448 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002449 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002450 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002451 }
mpagenkoaa3afe92021-05-21 16:20:58 +00002452 case OmciOnuSwUpgradeDone:
2453 {
2454 dh.upgradeSuccess = true
2455 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002456 default:
2457 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002458 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002459 }
2460 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002461}
2462
dbainbri4d3a0dc2020-12-02 00:33:42 +00002463func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002464 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002465 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302466 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002467 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002468 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002469 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302470 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002471 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002472 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002473 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002474 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002475 //store UniPort with the System-PortNumber key
2476 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002477 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002478 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002479 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2480 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002481 } //error logging already within UniPort method
2482 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002483 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002484 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002485 }
2486 }
2487}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002488
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002489func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2490 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2491 if pDevEntry == nil {
2492 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2493 return
2494 }
2495 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2496 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2497 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2498 for _, mgmtEntityID := range pptpInstKeys {
2499 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2500 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2501 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2502 i++
2503 }
2504 } else {
2505 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2506 }
2507 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2508 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2509 for _, mgmtEntityID := range veipInstKeys {
2510 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2511 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2512 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2513 i++
2514 }
2515 } else {
2516 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2517 }
2518 if i == 0 {
2519 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2520 }
2521}
2522
mpagenko3af1f032020-06-10 08:53:41 +00002523// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002524func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002525 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302526 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002527 // with following remark:
2528 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2529 // # load on the core
2530
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002531 // 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 +00002532
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002533 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002534 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002535 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002536 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302537 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002538 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002539 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002540 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 +00002541 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002542 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002543 }
mpagenko3af1f032020-06-10 08:53:41 +00002544 }
2545 }
2546}
2547
2548// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002549func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002550 // compare enableUniPortStateUpdate() above
2551 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2552 for uniNo, uniPort := range dh.uniEntityMap {
2553 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002554
2555 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002556 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302557 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002558 if !dh.isReconciling() {
2559 //maybe also use getter functions on uniPort - perhaps later ...
2560 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2561 } else {
2562 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2563 }
2564
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002565 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002566 }
2567}
2568
2569// ONU_Active/Inactive announcement on system KAFKA bus
2570// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002571func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002572 var de voltha.DeviceEvent
2573 eventContext := make(map[string]string)
2574 //Populating event context
2575 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002576 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002577 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002578 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302579 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002580 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 +00002581 }
2582 oltSerialNumber := parentDevice.SerialNumber
2583
2584 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2585 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2586 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302587 eventContext["olt-serial-number"] = oltSerialNumber
2588 eventContext["device-id"] = aDeviceID
2589 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002590 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
2591 if deviceEntry := dh.getOnuDeviceEntry(ctx, false); deviceEntry != nil {
2592 deviceEntry.mutexPersOnuConfig.RLock()
2593 eventContext["equipment-id"] = deviceEntry.sOnuPersistentData.PersEquipmentID
2594 deviceEntry.mutexPersOnuConfig.RUnlock()
2595 eventContext["software-version"] = deviceEntry.getActiveImageVersion(ctx)
2596 deviceEntry.mutexPersOnuConfig.RLock()
2597 eventContext["vendor"] = deviceEntry.sOnuPersistentData.PersVendorID
2598 deviceEntry.mutexPersOnuConfig.RUnlock()
2599 eventContext["inactive-software-version"] = deviceEntry.getInactiveImageVersion(ctx)
2600 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2601 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2602 } else {
2603 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2604 log.Fields{"device-id": aDeviceID})
2605 return
2606 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002607
2608 /* Populating device event body */
2609 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302610 de.ResourceId = aDeviceID
2611 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002612 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2613 de.Description = fmt.Sprintf("%s Event - %s - %s",
2614 cEventObjectType, cOnuActivatedEvent, "Raised")
2615 } else {
2616 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2617 de.Description = fmt.Sprintf("%s Event - %s - %s",
2618 cEventObjectType, cOnuActivatedEvent, "Cleared")
2619 }
2620 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002621 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2622 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302623 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002624 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002625 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302626 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002627}
2628
Himani Chawla4d908332020-08-31 12:30:20 +05302629// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002630func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002631 chLSFsm := make(chan Message, 2048)
2632 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302633 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002634 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002635 sFsmName = "LockStateFSM"
2636 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002637 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002638 sFsmName = "UnLockStateFSM"
2639 }
mpagenko3af1f032020-06-10 08:53:41 +00002640
dbainbri4d3a0dc2020-12-02 00:33:42 +00002641 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002642 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002643 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002644 return
2645 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002646 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002647 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002648 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302649 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002650 dh.pLockStateFsm = pLSFsm
2651 } else {
2652 dh.pUnlockStateFsm = pLSFsm
2653 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002654 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002655 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002656 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002657 }
2658}
2659
2660// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002661func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002662 /* Uni Port lock/unlock procedure -
2663 ***** should run via 'adminDone' state and generate the argument requested event *****
2664 */
2665 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302666 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002667 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2668 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2669 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002670 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302671 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002672 }
2673 } else {
2674 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2675 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2676 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002677 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302678 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002679 }
2680 }
2681 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002682 if pLSStatemachine.Is(uniStDisabled) {
2683 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002684 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002685 // maybe try a FSM reset and then again ... - TODO!!!
2686 } else {
2687 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002688 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002689 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002690 }
2691 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002692 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002693 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002694 // maybe try a FSM reset and then again ... - TODO!!!
2695 }
2696 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002697 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002698 // maybe try a FSM reset and then again ... - TODO!!!
2699 }
2700}
2701
mpagenko80622a52021-02-09 16:53:23 +00002702// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002703func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002704 //in here lockUpgradeFsm is already locked
2705 chUpgradeFsm := make(chan Message, 2048)
2706 var sFsmName = "OnuSwUpgradeFSM"
2707 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002708 if apDevEntry.PDevOmciCC == nil {
2709 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2710 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002711 }
mpagenko15ff4a52021-03-02 10:09:20 +00002712 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002713 sFsmName, chUpgradeFsm)
2714 if dh.pOnuUpradeFsm != nil {
2715 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2716 if pUpgradeStatemachine != nil {
2717 if pUpgradeStatemachine.Is(upgradeStDisabled) {
mpagenkoaa3afe92021-05-21 16:20:58 +00002718 dh.upgradeSuccess = false //for start of upgrade processing reset the last indication
mpagenko80622a52021-02-09 16:53:23 +00002719 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2720 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2721 // maybe try a FSM reset and then again ... - TODO!!!
2722 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2723 }
2724 /***** LockStateFSM started */
2725 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2726 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2727 } else {
2728 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2729 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2730 // maybe try a FSM reset and then again ... - TODO!!!
2731 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2732 }
2733 } else {
2734 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2735 // maybe try a FSM reset and then again ... - TODO!!!
2736 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2737 }
2738 } else {
2739 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2740 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2741 }
2742 return nil
2743}
2744
2745// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2746func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2747 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2748 "device-id": dh.deviceID})
2749 dh.lockUpgradeFsm.Lock()
2750 defer dh.lockUpgradeFsm.Unlock()
2751 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2752}
2753
mpagenko15ff4a52021-03-02 10:09:20 +00002754// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2755func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2756 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2757 if pDevEntry == nil {
2758 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2759 return
2760 }
2761
2762 dh.lockUpgradeFsm.RLock()
2763 defer dh.lockUpgradeFsm.RUnlock()
2764 if dh.pOnuUpradeFsm != nil {
2765 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2766 if pUpgradeStatemachine != nil {
2767 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2768 // (some manual forced commit could do without)
mpagenko1f8e8822021-06-25 14:10:21 +00002769 upgradeState := pUpgradeStatemachine.Current()
2770 if (upgradeState == upgradeStWaitForCommit) ||
2771 (upgradeState == upgradeStRequestingActivate) {
2772 // also include upgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00002773 // 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 +00002774 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00002775 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
2776 if errImg != nil {
2777 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
2778 log.Fields{"device-id": dh.deviceID})
2779 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
mpagenko15ff4a52021-03-02 10:09:20 +00002780 return
2781 }
mpagenko1f8e8822021-06-25 14:10:21 +00002782 if activeImageID == dh.pOnuUpradeFsm.inactiveImageMeID {
2783 if (upgradeState == upgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
2784 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
2785 if err := pUpgradeStatemachine.Event(upgradeEvActivationDone); err != nil {
2786 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
2787 return
2788 }
2789 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
2790 "state": upgradeState, "device-id": dh.deviceID})
2791 } else {
2792 //FSM in waitForCommit or (upgradeStRequestingActivate [lost ActivateResp] and commit allowed)
2793 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2794 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2795 return
2796 }
2797 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2798 "state": upgradeState, "device-id": dh.deviceID})
2799 }
2800 } else {
2801 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit/on ActivateResponse, but load did not start with expected image Id",
2802 log.Fields{"device-id": dh.deviceID})
2803 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2804 return
2805 }
mpagenko15ff4a52021-03-02 10:09:20 +00002806 } else {
2807 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2808 log.Fields{"device-id": dh.deviceID})
2809 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2810 return
2811 }
mpagenko183647c2021-06-08 15:25:04 +00002812 } else {
2813 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2814 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2815 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2816 if dh.pOnuUpradeFsm.inactiveImageMeID == activeImageID {
2817 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2818 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2819 dh.pOnuUpradeFsm.SetImageState(ctx, voltha.ImageState_IMAGE_ACTIVE)
2820 }
2821 }
mpagenko15ff4a52021-03-02 10:09:20 +00002822 }
2823 }
2824 } else {
2825 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2826 }
2827}
2828
Himani Chawla6d2ae152020-09-02 13:11:20 +05302829//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002830func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002831
2832 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002833 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07002834 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00002835 kvbackend := &db.Backend{
2836 Client: dh.pOpenOnuAc.kvClient,
2837 StoreType: dh.pOpenOnuAc.KVStoreType,
2838 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002839 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002840 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2841 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002842
mpagenkoaf801632020-07-03 10:00:42 +00002843 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002844}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002845func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302846 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002847
mpagenkodff5dda2020-08-28 11:52:01 +00002848 for _, field := range flow.GetOfbFields(apFlowItem) {
2849 switch field.Type {
2850 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2851 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002852 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002853 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2854 }
mpagenko01e726e2020-10-23 09:45:29 +00002855 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002856 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2857 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302858 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002859 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302860 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2861 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002862 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2863 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002864 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2865 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302866 return
mpagenkodff5dda2020-08-28 11:52:01 +00002867 }
2868 }
mpagenko01e726e2020-10-23 09:45:29 +00002869 */
mpagenkodff5dda2020-08-28 11:52:01 +00002870 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2871 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302872 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002873 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302874 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002875 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302876 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002877 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002878 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302879 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002880 }
2881 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2882 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302883 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002884 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002885 "PCP": loAddPcp})
2886 }
2887 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2888 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002889 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002890 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2891 }
2892 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2893 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002894 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002895 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2896 }
2897 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2898 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002899 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002900 "IPv4-DST": field.GetIpv4Dst()})
2901 }
2902 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2903 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002904 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002905 "IPv4-SRC": field.GetIpv4Src()})
2906 }
2907 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2908 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002909 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002910 "Metadata": field.GetTableMetadata()})
2911 }
2912 /*
2913 default:
2914 {
2915 //all other entires ignored
2916 }
2917 */
2918 }
2919 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302920}
mpagenkodff5dda2020-08-28 11:52:01 +00002921
dbainbri4d3a0dc2020-12-02 00:33:42 +00002922func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002923 for _, action := range flow.GetActions(apFlowItem) {
2924 switch action.Type {
2925 /* not used:
2926 case of.OfpActionType_OFPAT_OUTPUT:
2927 {
mpagenko01e726e2020-10-23 09:45:29 +00002928 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002929 "Output": action.GetOutput()})
2930 }
2931 */
2932 case of.OfpActionType_OFPAT_PUSH_VLAN:
2933 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002934 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002935 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2936 }
2937 case of.OfpActionType_OFPAT_SET_FIELD:
2938 {
2939 pActionSetField := action.GetSetField()
2940 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002941 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002942 "OxcmClass": pActionSetField.Field.OxmClass})
2943 }
2944 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302945 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002946 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302947 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002948 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302949 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002950 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302951 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002952 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002953 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002954 "Type": pActionSetField.Field.GetOfbField().Type})
2955 }
2956 }
2957 /*
2958 default:
2959 {
2960 //all other entires ignored
2961 }
2962 */
2963 }
2964 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302965}
2966
2967//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
ozgecanetsia82b91a62021-05-21 18:54:49 +03002968func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort,
2969 apFlowMetaData *voltha.FlowMetadata) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302970 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2971 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2972 var loAddPcp, loSetPcp uint8
2973 var loIPProto uint32
2974 /* the TechProfileId is part of the flow Metadata - compare also comment within
2975 * OLT-Adapter:openolt_flowmgr.go
2976 * Metadata 8 bytes:
2977 * Most Significant 2 Bytes = Inner VLAN
2978 * Next 2 Bytes = Tech Profile ID(TPID)
2979 * Least Significant 4 Bytes = Port ID
2980 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2981 * subscriber related flows.
2982 */
2983
dbainbri4d3a0dc2020-12-02 00:33:42 +00002984 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302985 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002986 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302987 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002988 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302989 }
mpagenko551a4d42020-12-08 18:09:20 +00002990 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002991 loCookie := apFlowItem.GetCookie()
2992 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002993 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002994 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302995
dbainbri4d3a0dc2020-12-02 00:33:42 +00002996 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002997 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302998 if loIPProto == 2 {
2999 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3000 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003001 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
3002 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303003 return nil
3004 }
mpagenko01e726e2020-10-23 09:45:29 +00003005 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003006 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003007
3008 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003009 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003010 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
3011 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3012 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3013 //TODO!!: Use DeviceId within the error response to rwCore
3014 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00003015 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003016 }
3017 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003018 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003019 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3020 } else {
3021 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3022 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3023 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303024 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003025 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003026 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003027 }
mpagenko9a304ea2020-12-16 15:54:01 +00003028
3029 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenko37047052021-07-27 10:01:29 +00003030 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3031 // when different rules are requested concurrently for the same uni
3032 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3033 dh.lockVlanConfig.Lock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003034 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID, "tpID": loTpID, "uniID": apUniPort.uniID})
3035 var meter *voltha.OfpMeterConfig
3036 if apFlowMetaData != nil {
3037 meter = apFlowMetaData.Meters[0]
3038 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303039 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003040 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003041 loMatchVlan, loSetVlan, loSetPcp, false, meter)
mpagenko37047052021-07-27 10:01:29 +00003042 dh.lockVlanConfig.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +00003043 return err
mpagenkodff5dda2020-08-28 11:52:01 +00003044 }
mpagenko37047052021-07-27 10:01:29 +00003045 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003046 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false, meter)
mpagenko37047052021-07-27 10:01:29 +00003047 dh.lockVlanConfig.Unlock()
3048 return err
mpagenko01e726e2020-10-23 09:45:29 +00003049}
3050
3051//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00003052func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00003053 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3054 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3055 //no extra check is done on the rule parameters
3056 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3057 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3058 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3059 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003060 // - 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 +00003061 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003062 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003063
3064 /* TT related temporary workaround - should not be needed anymore
3065 for _, field := range flow.GetOfbFields(apFlowItem) {
3066 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3067 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00003068 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003069 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3070 if loIPProto == 2 {
3071 // 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 +00003072 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00003073 log.Fields{"device-id": dh.deviceID})
3074 return nil
3075 }
3076 }
3077 } //for all OfbFields
3078 */
3079
mpagenko9a304ea2020-12-16 15:54:01 +00003080 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003081 dh.lockVlanConfig.RLock()
3082 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00003083 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003084 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00003085 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003086 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00003087 log.Fields{"device-id": dh.deviceID})
3088 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003089 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00003090 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00003091
mpagenko01e726e2020-10-23 09:45:29 +00003092 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00003093}
3094
Himani Chawla26e555c2020-08-31 12:30:20 +05303095// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003096// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko37047052021-07-27 10:01:29 +00003097// precondition: dh.lockVlanConfig is locked by the caller!
mpagenko551a4d42020-12-08 18:09:20 +00003098func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003099 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
mpagenkodff5dda2020-08-28 11:52:01 +00003100 chVlanFilterFsm := make(chan Message, 2048)
3101
dbainbri4d3a0dc2020-12-02 00:33:42 +00003102 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003103 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003104 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303105 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003106 }
3107
dbainbri4d3a0dc2020-12-02 00:33:42 +00003108 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00003109 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003110 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter)
mpagenkodff5dda2020-08-28 11:52:01 +00003111 if pVlanFilterFsm != nil {
mpagenko37047052021-07-27 10:01:29 +00003112 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3113 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Himani Chawla26e555c2020-08-31 12:30:20 +05303114 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003115 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3116 if pVlanFilterStatemachine != nil {
3117 if pVlanFilterStatemachine.Is(vlanStDisabled) {
3118 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003119 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05303120 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003121 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303122 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003123 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05303124 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3125 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003126 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003127 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003128 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303129 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003130 }
3131 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003132 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003133 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303134 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003135 }
3136 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003137 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003138 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05303139 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003140 }
3141 return nil
3142}
3143
mpagenkofc4f56e2020-11-04 17:17:49 +00003144//VerifyVlanConfigRequest checks on existence of a given uniPort
3145// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003146func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003147 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
3148 var pCurrentUniPort *onuUniPort
3149 for _, uniPort := range dh.uniEntityMap {
3150 // only if this port is validated for operState transfer
3151 if uniPort.uniID == uint8(aUniID) {
3152 pCurrentUniPort = uniPort
3153 break //found - end search loop
3154 }
3155 }
3156 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003157 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00003158 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
3159 return
3160 }
mpagenko551a4d42020-12-08 18:09:20 +00003161 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003162}
3163
mpagenkodff5dda2020-08-28 11:52:01 +00003164//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00003165func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003166 //TODO!! verify and start pending flow configuration
3167 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3168 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003169
3170 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303171 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003172 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003173 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
3174 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3175 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003176 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
3177 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
3178 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
3179 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
3180 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3181 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3182 } else {
3183 /***** UniVlanConfigFsm continued */
3184 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
3185 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3186 "UniPort": apUniPort.portNo})
3187 }
3188 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
3189 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
3190 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3191 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3192 } else {
3193 /***** UniVlanConfigFsm continued */
3194 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3195 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3196 "UniPort": apUniPort.portNo})
3197 }
mpagenkodff5dda2020-08-28 11:52:01 +00003198 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003199 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3200 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003201 "UniPort": apUniPort.portNo})
3202 }
3203 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003204 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3205 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3206 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003207 }
3208 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003209 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003210 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003211 }
mpagenkof1fc3862021-02-16 10:09:52 +00003212 } else {
3213 dh.lockVlanConfig.RUnlock()
3214 }
mpagenkodff5dda2020-08-28 11:52:01 +00003215}
3216
3217//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3218// 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 +00003219func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3220 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003221 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3222 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003223 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303224 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003225 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003226}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003227
mpagenkof1fc3862021-02-16 10:09:52 +00003228//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3229func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3230 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3231 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3232 // obviously then parallel processing on the cancel must be avoided
3233 // deadline context to ensure completion of background routines waited for
3234 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3235 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3236 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3237
3238 aPDevEntry.resetKvProcessingErrorIndication()
3239 var wg sync.WaitGroup
3240 wg.Add(1) // for the 1 go routine to finish
3241
3242 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3243 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3244
3245 return aPDevEntry.getKvProcessingErrorIndication()
3246}
3247
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003248//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3249//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003250func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3251 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003252
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003253 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003254 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003255 return nil
3256 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003257 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003258
dbainbri4d3a0dc2020-12-02 00:33:42 +00003259 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003260 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003261 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003262 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3263 }
3264 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3265
mpagenkof1fc3862021-02-16 10:09:52 +00003266 if aWriteToKvStore {
3267 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3268 }
3269 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003270}
3271
dbainbri4d3a0dc2020-12-02 00:33:42 +00003272func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003273 defer cancel() //ensure termination of context (may be pro forma)
3274 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003275 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003276 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003277}
3278
dbainbri4d3a0dc2020-12-02 00:33:42 +00003279func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003280
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003281 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003282 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003283 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003284 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3285 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003286 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003287 return err
3288 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003289 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003290 return nil
3291 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003292 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003293 return nil
3294}
3295
dbainbri4d3a0dc2020-12-02 00:33:42 +00003296func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3297 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003298 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003299 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003300 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3301 }
mpagenkof1fc3862021-02-16 10:09:52 +00003302 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003303}
3304
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003305// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003306// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003307func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3308 dh.lockDevice.RLock()
3309 defer dh.lockDevice.RUnlock()
3310 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3311 return uniPort.entityID, nil
3312 }
3313 return 0, errors.New("error-fetching-uni-port")
3314}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003315
3316// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003317func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3318 var errorsList []error
3319 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 -08003320
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003321 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3322 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3323 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3324
3325 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3326 // successfully.
3327 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3328 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3329 if len(errorsList) > 0 {
3330 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3331 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003332 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003333 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3334 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003335}
3336
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003337func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3338 var err error
3339 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003340 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003341
3342 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3343 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3344 errorsList = append(errorsList, err)
3345 }
3346 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003347 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003348
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003349 return errorsList
3350}
3351
3352func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3353 var err error
3354 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003355 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003356 // Check if group metric related config is updated
3357 for _, v := range pmConfigs.Groups {
3358 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3359 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3360 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3361
3362 if ok && m.frequency != v.GroupFreq {
3363 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3364 errorsList = append(errorsList, err)
3365 }
3366 }
3367 if ok && m.enabled != v.Enabled {
3368 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3369 errorsList = append(errorsList, err)
3370 }
3371 }
3372 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003373 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003374 return errorsList
3375}
3376
3377func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3378 var err error
3379 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003380 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003381 // Check if standalone metric related config is updated
3382 for _, v := range pmConfigs.Metrics {
3383 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003384 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003385 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3386
3387 if ok && m.frequency != v.SampleFreq {
3388 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3389 errorsList = append(errorsList, err)
3390 }
3391 }
3392 if ok && m.enabled != v.Enabled {
3393 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3394 errorsList = append(errorsList, err)
3395 }
3396 }
3397 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003398 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003399 return errorsList
3400}
3401
3402// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003403func (dh *deviceHandler) startCollector(ctx context.Context) {
3404 logger.Debugf(ctx, "startingCollector")
3405
3406 // Start routine to process OMCI GET Responses
3407 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303408 // Create Extended Frame PM ME
3409 go dh.pOnuMetricsMgr.createEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003410 // Initialize the next metric collection time.
3411 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3412 // reset like onu rebooted.
3413 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003414 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003415 for {
3416 select {
3417 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003418 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003419 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003420 // Stop the L2 PM FSM
3421 go func() {
3422 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3423 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3424 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3425 }
3426 } else {
3427 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3428 }
3429 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003430 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3431 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3432 }
3433 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3434 dh.pOnuMetricsMgr.stopTicks <- true
3435 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003436
Girish Gowdrae09a6202021-01-12 18:10:59 -08003437 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003438 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3439 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3440 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3441 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3442 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003443 // Update the next metric collection time.
3444 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003445 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003446 } else {
3447 if dh.pmConfigs.Grouped { // metrics are managed as a group
3448 // parse through the group and standalone metrics to see it is time to collect their metrics
3449 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003450
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003451 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3452 // 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 -08003453 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3454 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003455 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3456 }
3457 }
3458 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3459 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3460 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3461 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3462 }
3463 }
3464 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3465
3466 // parse through the group and update the next metric collection time
3467 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3468 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3469 // 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 -08003470 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3471 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003472 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3473 }
3474 }
3475 // parse through the standalone metrics and update the next metric collection time
3476 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3477 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3478 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3479 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3480 }
3481 }
3482 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3483 } /* else { // metrics are not managed as a group
3484 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3485 } */
3486 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003487 }
3488 }
3489}
kesavandfdf77632021-01-26 23:40:33 -05003490
3491func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3492
3493 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3494 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3495}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003496
Himani Chawla43f95ff2021-06-03 00:24:12 +05303497func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3498 if dh.pOnuMetricsMgr == nil {
3499 return &extension.SingleGetValueResponse{
3500 Response: &extension.GetValueResponse{
3501 Status: extension.GetValueResponse_ERROR,
3502 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3503 },
3504 }
3505 }
3506 resp := dh.pOnuMetricsMgr.collectEthernetFrameExtendedPMCounters(ctx)
3507 return resp
3508}
3509
mpagenkof1fc3862021-02-16 10:09:52 +00003510func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3511 if pFsm == nil {
3512 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003513 }
mpagenkof1fc3862021-02-16 10:09:52 +00003514 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003515}
3516
mpagenkof1fc3862021-02-16 10:09:52 +00003517func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3518 var pFsm *fsm.FSM
3519 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3520 switch omciFsm {
3521 case cUploadFsm:
3522 {
3523 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3524 }
3525 case cDownloadFsm:
3526 {
3527 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3528 }
3529 case cUniLockFsm:
3530 {
3531 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3532 }
3533 case cUniUnLockFsm:
3534 {
3535 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3536 }
3537 case cL2PmFsm:
3538 {
3539 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3540 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3541 } else {
3542 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003543 }
3544 }
mpagenko80622a52021-02-09 16:53:23 +00003545 case cOnuUpgradeFsm:
3546 {
3547 dh.lockUpgradeFsm.RLock()
3548 defer dh.lockUpgradeFsm.RUnlock()
3549 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3550 }
mpagenkof1fc3862021-02-16 10:09:52 +00003551 default:
3552 {
3553 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3554 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3555 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003556 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003557 }
mpagenkof1fc3862021-02-16 10:09:52 +00003558 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003559}
3560
mpagenkof1fc3862021-02-16 10:09:52 +00003561func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3562 for _, v := range dh.pOnuTP.pAniConfigFsm {
3563 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003564 return false
3565 }
3566 }
3567 return true
3568}
3569
mpagenkof1fc3862021-02-16 10:09:52 +00003570func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3571 dh.lockVlanConfig.RLock()
3572 defer dh.lockVlanConfig.RUnlock()
3573 for _, v := range dh.UniVlanConfigFsmMap {
3574 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3575 return false
3576 }
3577 }
3578 return true //FSM not active - so there is no activity on omci
3579}
3580
3581func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3582 dh.lockVlanConfig.RLock()
3583 defer dh.lockVlanConfig.RUnlock()
3584 for _, v := range dh.UniVlanConfigFsmMap {
3585 if v.pAdaptFsm.pFsm != nil {
3586 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3587 return true //there is at least one VLAN FSM with some active configuration
3588 }
3589 }
3590 }
3591 return false //there is no VLAN FSM with some active configuration
3592}
3593
3594func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3595 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3596 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3597 return false
3598 }
3599 }
3600 // a further check is done to identify, if at least some data traffic related configuration exists
3601 // 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])
3602 return dh.checkUserServiceExists(ctx)
3603}
3604
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003605func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3606 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3607 if err := dh.resetFsms(ctx, false); err != nil {
3608 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3609 // TODO: fatal error reset ONU, delete deviceHandler!
3610 return
3611 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003612 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003613 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003614}
3615
3616func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3617 dh.mutexCollectorFlag.Lock()
3618 dh.collectorIsRunning = flagValue
3619 dh.mutexCollectorFlag.Unlock()
3620}
3621
3622func (dh *deviceHandler) getCollectorIsRunning() bool {
3623 dh.mutexCollectorFlag.RLock()
3624 flagValue := dh.collectorIsRunning
3625 dh.mutexCollectorFlag.RUnlock()
3626 return flagValue
3627}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303628
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303629func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3630 dh.mutextAlarmManagerFlag.Lock()
3631 dh.alarmManagerIsRunning = flagValue
3632 dh.mutextAlarmManagerFlag.Unlock()
3633}
3634
Himani Chawla1472c682021-03-17 17:11:14 +05303635func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303636 dh.mutextAlarmManagerFlag.RLock()
3637 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303638 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303639 dh.mutextAlarmManagerFlag.RUnlock()
3640 return flagValue
3641}
3642
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303643func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3644 logger.Debugf(ctx, "startingAlarmManager")
3645
3646 // Start routine to process OMCI GET Responses
3647 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303648 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303649 if stop := <-dh.stopAlarmManager; stop {
3650 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303651 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303652 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303653 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3654 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3655 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303656 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303657 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303658 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3659 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303660 }
3661}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003662
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003663func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003664 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003665
Maninder7961d722021-06-16 22:10:28 +05303666 connectStatus := voltha.ConnectStatus_UNREACHABLE
3667 operState := voltha.OperStatus_UNKNOWN
3668
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003669 if !dh.isReconciling() {
3670 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003671 logger.Debugw(ctx, "wait for channel signal or timeout",
3672 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003673 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003674 case success := <-dh.chReconcilingFinished:
3675 if success {
Maninderb5187552021-03-23 22:23:42 +05303676 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3677 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3678 log.Fields{"device-id": dh.deviceID})
3679 } else {
Maninderb5187552021-03-23 22:23:42 +05303680 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3681 connectStatus = voltha.ConnectStatus_REACHABLE
3682 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3683 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3684 operState = voltha.OperStatus_ACTIVE
3685 } else {
3686 operState = voltha.OperStatus_ACTIVATING
3687 }
3688 }
3689 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3690 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3691 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3692 operState = voltha.OperStatus_DISCOVERED
3693 }
3694
3695 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303696 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003697 logger.Debugw(ctx, "reconciling has been finished in time",
3698 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303699 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, operState); err != nil {
3700 logger.Errorw(ctx, "unable to update device state to core",
3701 log.Fields{"device-id": dh.deviceID, "Err": err})
3702 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003703 } else {
Maninderb5187552021-03-23 22:23:42 +05303704 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003705 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303706
3707 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3708 logger.Errorw(ctx, "No valid OnuDevice",
3709 log.Fields{"device-id": dh.deviceID})
3710 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3711 connectStatus = voltha.ConnectStatus_REACHABLE
3712 }
3713
3714 dh.deviceReconcileFailedUpdate(ctx, drReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003715 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003716 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003717 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3718 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303719
3720 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3721 logger.Errorw(ctx, "No valid OnuDevice",
3722 log.Fields{"device-id": dh.deviceID})
3723 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3724 connectStatus = voltha.ConnectStatus_REACHABLE
3725 }
3726
3727 dh.deviceReconcileFailedUpdate(ctx, drReconcileMaxTimeout, connectStatus)
3728
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003729 }
3730 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003731 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003732 dh.mutexReconcilingFlag.Unlock()
3733 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003734 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003735 dh.mutexReconcilingFlag.Lock()
3736 if skipOnuConfig {
3737 dh.reconciling = cSkipOnuConfigReconciling
3738 } else {
3739 dh.reconciling = cOnuConfigReconciling
3740 }
3741 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003742}
3743
Girish Gowdra50e56422021-06-01 16:46:04 -07003744func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool) {
3745 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID, "success": success})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003746 if dh.isReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07003747 dh.chReconcilingFinished <- success
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003748 } else {
3749 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3750 }
3751}
3752
3753func (dh *deviceHandler) isReconciling() bool {
3754 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003755 defer dh.mutexReconcilingFlag.RUnlock()
3756 return dh.reconciling != cNoReconciling
3757}
3758
3759func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3760 dh.mutexReconcilingFlag.RLock()
3761 defer dh.mutexReconcilingFlag.RUnlock()
3762 return dh.reconciling == cSkipOnuConfigReconciling
3763}
3764
3765func (dh *deviceHandler) setDeviceReason(value uint8) {
3766 dh.mutexDeviceReason.Lock()
3767 dh.deviceReason = value
3768 dh.mutexDeviceReason.Unlock()
3769}
3770
3771func (dh *deviceHandler) getDeviceReason() uint8 {
3772 dh.mutexDeviceReason.RLock()
3773 value := dh.deviceReason
3774 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003775 return value
3776}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003777
3778func (dh *deviceHandler) getDeviceReasonString() string {
3779 return deviceReasonMap[dh.getDeviceReason()]
3780}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003781
3782func (dh *deviceHandler) setReconcilingFlows(value bool) {
3783 dh.mutexReconcilingFlowsFlag.Lock()
3784 dh.reconcilingFlows = value
3785 dh.mutexReconcilingFlowsFlag.Unlock()
3786}
3787
3788func (dh *deviceHandler) isReconcilingFlows() bool {
3789 dh.mutexReconcilingFlowsFlag.RLock()
3790 value := dh.reconcilingFlows
3791 dh.mutexReconcilingFlowsFlag.RUnlock()
3792 return value
3793}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003794
3795func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3796 dh.mutexReadyForOmciConfig.Lock()
3797 dh.readyForOmciConfig = flagValue
3798 dh.mutexReadyForOmciConfig.Unlock()
3799}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003800func (dh *deviceHandler) isReadyForOmciConfig() bool {
3801 dh.mutexReadyForOmciConfig.RLock()
3802 flagValue := dh.readyForOmciConfig
3803 dh.mutexReadyForOmciConfig.RUnlock()
3804 return flagValue
3805}
Maninder7961d722021-06-16 22:10:28 +05303806
3807func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
3808 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
3809 logger.Errorw(ctx, "unable to update device reason to core",
3810 log.Fields{"device-id": dh.deviceID, "Err": err})
3811 }
3812
3813 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
3814 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, voltha.OperStatus_RECONCILING_FAILED); err != nil {
3815 logger.Errorw(ctx, "unable to update device state to core",
3816 log.Fields{"device-id": dh.deviceID, "Err": err})
3817 }
3818}