blob: 1cf414a67d86a6da9c92ea0ee9c0b6fdec6ce44a [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000022 "errors"
23 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000024 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000025 "sync"
26 "time"
27
mpagenko1f8e8822021-06-25 14:10:21 +000028 "github.com/opencord/voltha-protos/v4/go/tech_profile"
29
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000030 "github.com/gogo/protobuf/proto"
31 "github.com/golang/protobuf/ptypes"
32 "github.com/looplab/fsm"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000033 me "github.com/opencord/omci-lib-go/generated"
Girish Gowdra50e56422021-06-01 16:46:04 -070034 "github.com/opencord/voltha-lib-go/v5/pkg/adapters/adapterif"
35 "github.com/opencord/voltha-lib-go/v5/pkg/db"
36 "github.com/opencord/voltha-lib-go/v5/pkg/events/eventif"
37 flow "github.com/opencord/voltha-lib-go/v5/pkg/flows"
38 "github.com/opencord/voltha-lib-go/v5/pkg/log"
dbainbri4d3a0dc2020-12-02 00:33:42 +000039 vc "github.com/opencord/voltha-protos/v4/go/common"
kesavandfdf77632021-01-26 23:40:33 -050040 "github.com/opencord/voltha-protos/v4/go/extension"
dbainbri4d3a0dc2020-12-02 00:33:42 +000041 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
42 "github.com/opencord/voltha-protos/v4/go/openflow_13"
43 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
44 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
45 oop "github.com/opencord/voltha-protos/v4/go/openolt"
46 "github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000047)
48
49/*
50// Constants for number of retries and for timeout
51const (
52 MaxRetry = 10
53 MaxTimeOutInMs = 500
54)
55*/
56
mpagenko1cc3cb42020-07-27 15:24:38 +000057const (
58 // events of Device FSM
59 devEvDeviceInit = "devEvDeviceInit"
60 devEvGrpcConnected = "devEvGrpcConnected"
61 devEvGrpcDisconnected = "devEvGrpcDisconnected"
62 devEvDeviceUpInd = "devEvDeviceUpInd"
63 devEvDeviceDownInd = "devEvDeviceDownInd"
64)
65const (
66 // states of Device FSM
67 devStNull = "devStNull"
68 devStDown = "devStDown"
69 devStInit = "devStInit"
70 devStConnected = "devStConnected"
71 devStUp = "devStUp"
72)
73
Holger Hildebrandt24d51952020-05-04 14:03:42 +000074//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
75const (
Himani Chawla4d908332020-08-31 12:30:20 +053076 pon = voltha.EventSubCategory_PON
77 //olt = voltha.EventSubCategory_OLT
78 //ont = voltha.EventSubCategory_ONT
79 //onu = voltha.EventSubCategory_ONU
80 //nni = voltha.EventSubCategory_NNI
81 //service = voltha.EventCategory_SERVICE
82 //security = voltha.EventCategory_SECURITY
83 equipment = voltha.EventCategory_EQUIPMENT
84 //processing = voltha.EventCategory_PROCESSING
85 //environment = voltha.EventCategory_ENVIRONMENT
86 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000087)
88
89const (
90 cEventObjectType = "ONU"
91)
92const (
93 cOnuActivatedEvent = "ONU_ACTIVATED"
94)
95
Holger Hildebrandt10d98192021-01-27 15:29:31 +000096type usedOmciConfigFsms int
97
98const (
99 cUploadFsm usedOmciConfigFsms = iota
100 cDownloadFsm
101 cUniLockFsm
102 cUniUnLockFsm
103 cAniConfigFsm
104 cUniVlanConfigFsm
Girish Gowdrae0140f02021-02-02 16:55:09 -0800105 cL2PmFsm
mpagenko80622a52021-02-09 16:53:23 +0000106 cOnuUpgradeFsm
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000107)
108
mpagenkof1fc3862021-02-16 10:09:52 +0000109type omciIdleCheckStruct struct {
110 omciIdleCheckFunc func(*deviceHandler, context.Context, usedOmciConfigFsms, string) bool
111 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000112}
113
mpagenkof1fc3862021-02-16 10:09:52 +0000114var fsmOmciIdleStateFuncMap = map[usedOmciConfigFsms]omciIdleCheckStruct{
115 cUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibUlFsmIdleState},
116 cDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibDlFsmIdleState},
117 cUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
118 cUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
119 cAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, cAniFsmIdleState},
120 cUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, cVlanFsmIdleState},
121 cL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cL2PmFsmIdleState},
mpagenko80622a52021-02-09 16:53:23 +0000122 cOnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cOnuUpgradeFsmIdleState},
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000123}
124
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000125const (
126 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000127 drUnset = 0
128 drActivatingOnu = 1
129 drStartingOpenomci = 2
130 drDiscoveryMibsyncComplete = 3
131 drInitialMibDownloaded = 4
132 drTechProfileConfigDownloadSuccess = 5
133 drOmciFlowsPushed = 6
134 drOmciAdminLock = 7
135 drOnuReenabled = 8
136 drStoppingOpenomci = 9
137 drRebooting = 10
138 drOmciFlowsDeleted = 11
139 drTechProfileConfigDeleteSuccess = 12
Maninder7961d722021-06-16 22:10:28 +0530140 drReconcileFailed = 13
141 drReconcileMaxTimeout = 14
142 drReconcileCanceled = 15
Girish Gowdra50e56422021-06-01 16:46:04 -0700143 drTechProfileConfigDownloadFailed = 16
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000144)
145
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000146var deviceReasonMap = map[uint8]string{
147 drUnset: "unset",
148 drActivatingOnu: "activating-onu",
149 drStartingOpenomci: "starting-openomci",
150 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
151 drInitialMibDownloaded: "initial-mib-downloaded",
152 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
Girish Gowdra50e56422021-06-01 16:46:04 -0700153 drTechProfileConfigDownloadFailed: "tech-profile-config-download-failed",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000154 drOmciFlowsPushed: "omci-flows-pushed",
155 drOmciAdminLock: "omci-admin-lock",
156 drOnuReenabled: "onu-reenabled",
157 drStoppingOpenomci: "stopping-openomci",
158 drRebooting: "rebooting",
159 drOmciFlowsDeleted: "omci-flows-deleted",
160 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
Maninder7961d722021-06-16 22:10:28 +0530161 drReconcileFailed: "reconcile-failed",
162 drReconcileMaxTimeout: "reconcile-max-timeout",
163 drReconcileCanceled: "reconciling-canceled",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000164}
165
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000166const (
167 cNoReconciling = iota
168 cOnuConfigReconciling
169 cSkipOnuConfigReconciling
170)
171
Himani Chawla6d2ae152020-09-02 13:11:20 +0530172//deviceHandler will interact with the ONU ? device.
173type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000174 deviceID string
175 DeviceType string
176 adminState string
177 device *voltha.Device
178 logicalDeviceID string
179 ProxyAddressID string
180 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530181 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000182 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000183
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000184 coreProxy adapterif.CoreProxy
185 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530186 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000187
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800188 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800189
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000190 pOpenOnuAc *OpenONUAC
191 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530192 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000193 deviceEntrySet chan bool //channel for DeviceEntry set event
194 pOnuOmciDevice *OnuDeviceEntry
195 pOnuTP *onuUniTechProf
196 pOnuMetricsMgr *onuMetricsManager
197 pAlarmMgr *onuAlarmManager
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700198 pSelfTestHdlr *selfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000199 exitChannel chan int
200 lockDevice sync.RWMutex
201 pOnuIndication *oop.OnuIndication
202 deviceReason uint8
203 mutexDeviceReason sync.RWMutex
204 pLockStateFsm *lockStateFsm
205 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000206
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000207 //flowMgr *OpenOltFlowMgr
208 //eventMgr *OpenOltEventMgr
209 //resourceMgr *rsrcMgr.OpenOltResourceMgr
210
211 //discOnus sync.Map
212 //onus sync.Map
213 //portStats *OpenOltStatisticsMgr
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000214 collectorIsRunning bool
215 mutexCollectorFlag sync.RWMutex
216 stopCollector chan bool
217 alarmManagerIsRunning bool
218 mutextAlarmManagerFlag sync.RWMutex
219 stopAlarmManager chan bool
220 stopHeartbeatCheck chan bool
221 uniEntityMap map[uint32]*onuUniPort
222 mutexKvStoreContext sync.Mutex
223 lockVlanConfig sync.RWMutex
224 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
225 lockUpgradeFsm sync.RWMutex
226 pOnuUpradeFsm *OnuUpgradeFsm
227 reconciling uint8
228 mutexReconcilingFlag sync.RWMutex
229 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000230 reconcilingFlows bool
231 mutexReconcilingFlowsFlag sync.RWMutex
232 chReconcilingFlowsFinished chan bool //channel to indicate that reconciling of flows has been finished
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000233 mutexReadyForOmciConfig sync.RWMutex
234 readyForOmciConfig bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000235 deletionInProgress bool
236 mutexDeletionInProgressFlag sync.RWMutex
mpagenkoaa3afe92021-05-21 16:20:58 +0000237 upgradeSuccess bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000238}
239
Himani Chawla6d2ae152020-09-02 13:11:20 +0530240//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530241func newDeviceHandler(ctx context.Context, cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530242 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000243 dh.coreProxy = cp
244 dh.AdapterProxy = ap
245 dh.EventProxy = ep
246 cloned := (proto.Clone(device)).(*voltha.Device)
247 dh.deviceID = cloned.Id
248 dh.DeviceType = cloned.Type
249 dh.adminState = "up"
250 dh.device = cloned
251 dh.pOpenOnuAc = adapter
252 dh.exitChannel = make(chan int, 1)
253 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000254 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000255 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000256 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530257 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530258 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000259 dh.stopHeartbeatCheck = make(chan bool, 2)
260 //dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000261 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530262 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000263 dh.lockVlanConfig = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000264 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000265 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000266 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000267 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000268 dh.reconcilingFlows = false
269 dh.chReconcilingFlowsFinished = make(chan bool)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000270 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000271 dh.deletionInProgress = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000272
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800273 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
274 dh.pmConfigs = cloned.PmConfigs
275 } /* else {
276 // will be populated when onu_metrics_mananger is initialized.
277 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800278
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000279 // Device related state machine
280 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000281 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000282 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000283 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
284 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
285 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
286 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
287 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000288 },
289 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000290 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
291 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
292 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
293 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
294 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
295 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
296 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
297 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000298 },
299 )
mpagenkoaf801632020-07-03 10:00:42 +0000300
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000301 return &dh
302}
303
Himani Chawla6d2ae152020-09-02 13:11:20 +0530304// start save the device to the data model
305func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000306 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000307 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000308 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000309}
310
Himani Chawla4d908332020-08-31 12:30:20 +0530311/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000312// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530313func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000314 logger.Debug("stopping-device-handler")
315 dh.exitChannel <- 1
316}
Himani Chawla4d908332020-08-31 12:30:20 +0530317*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000318
319// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530320// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000321
Girish Gowdrae0140f02021-02-02 16:55:09 -0800322//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530323func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000324 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000325
dbainbri4d3a0dc2020-12-02 00:33:42 +0000326 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000327 if dh.pDeviceStateFsm.Is(devStNull) {
328 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000329 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000330 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000331 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800332 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
333 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800334 // Now, set the initial PM configuration for that device
335 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
336 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
337 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800338 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000339 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000340 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000341 }
342
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000343}
344
mpagenko057889c2021-01-21 16:51:58 +0000345func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530346 msgBody := msg.GetBody()
347 omciMsg := &ic.InterAdapterOmciMessage{}
348 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000349 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530350 "device-id": dh.deviceID, "error": err})
351 return err
352 }
353
mpagenko80622a52021-02-09 16:53:23 +0000354 /* msg print moved symmetrically to omci_cc, if wanted here as additional debug, than perhaps only based on additional debug setting!
Himani Chawla26e555c2020-08-31 12:30:20 +0530355 //assuming omci message content is hex coded!
356 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000357 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530358 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000359 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000360 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530361 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000362 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000363 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000364 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000365 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"rxMsg": omciMsg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530366 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000367 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000368 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530369}
370
Himani Chawla6d2ae152020-09-02 13:11:20 +0530371func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000372 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530373 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000374
dbainbri4d3a0dc2020-12-02 00:33:42 +0000375 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000376
dbainbri4d3a0dc2020-12-02 00:33:42 +0000377 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000378 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000379 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000380 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
381 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530382 if dh.pOnuTP == nil {
383 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000384 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530385 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000386 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530387 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000388 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000389 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000390 "device-state": dh.getDeviceReasonString()})
391 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530392 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000393 //previous state test here was just this one, now extended for more states to reject the SetRequest:
394 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
395 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530396
397 msgBody := msg.GetBody()
398 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
399 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000400 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530401 "device-id": dh.deviceID, "error": err})
402 return err
403 }
404
405 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000406 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
407 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530408 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000409 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000410
411 if techProfMsg.UniId > 255 {
412 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
413 techProfMsg.UniId, dh.deviceID))
414 }
415 uniID := uint8(techProfMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700416 tpID, err := GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800417 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700418 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800419 return err
420 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700421 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000422
Girish Gowdra50e56422021-06-01 16:46:04 -0700423 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530424
Girish Gowdra50e56422021-06-01 16:46:04 -0700425 switch tpInst := techProfMsg.TechTpInstance.(type) {
426 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance:
427 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
428 // if there has been some change for some uni TechProfilePath
429 //in order to allow concurrent calls to other dh instances we do not wait for execution here
430 //but doing so we can not indicate problems to the caller (who does what with that then?)
431 //by now we just assume straightforward successful execution
432 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
433 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530434
Girish Gowdra50e56422021-06-01 16:46:04 -0700435 // deadline context to ensure completion of background routines waited for
436 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
437 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
438 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000439
Girish Gowdra50e56422021-06-01 16:46:04 -0700440 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
441
442 var wg sync.WaitGroup
443 wg.Add(1) // for the 1 go routine to finish
444 // attention: deadline completion check and wg.Done is to be done in both routines
445 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
446 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
447 if tpErr := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
448 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.deviceID, "err": tpErr, "tp-path": techProfMsg.TpInstancePath})
449 return tpErr
450 }
451 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
452 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
453 pDevEntry.resetKvProcessingErrorIndication()
454 wg.Add(1) // for the 1 go routine to finish
455 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
456 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
457 if kvErr := pDevEntry.getKvProcessingErrorIndication(); kvErr != nil {
458 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.deviceID, "err": kvErr, "tp-path": techProfMsg.TpInstancePath})
459 return kvErr
460 }
461 return nil
462 default:
463 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"tp-path": techProfMsg.TpInstancePath})
464 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700465 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530466 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000467 // no change, nothing really to do - return success
Girish Gowdra50e56422021-06-01 16:46:04 -0700468 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530469 return nil
470}
471
Himani Chawla6d2ae152020-09-02 13:11:20 +0530472func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000473 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530474 msg *ic.InterAdapterMessage) error {
475
dbainbri4d3a0dc2020-12-02 00:33:42 +0000476 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000477
dbainbri4d3a0dc2020-12-02 00:33:42 +0000478 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000479 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000480 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000481 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
482 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530483 if dh.pOnuTP == nil {
484 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000485 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530486 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000487 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530488 }
489
490 msgBody := msg.GetBody()
491 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
492 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000493 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530494 "device-id": dh.deviceID, "error": err})
495 return err
496 }
497
498 //compare TECH_PROFILE_DOWNLOAD_REQUEST
499 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000500 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530501
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000502 if delGemPortMsg.UniId > 255 {
503 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
504 delGemPortMsg.UniId, dh.deviceID))
505 }
506 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700507 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800508 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700509 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800510 return err
511 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530512
mpagenkofc4f56e2020-11-04 17:17:49 +0000513 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000514
mpagenkofc4f56e2020-11-04 17:17:49 +0000515 // deadline context to ensure completion of background routines waited for
516 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
517 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000518
Girish Gowdra041dcb32020-11-16 16:54:30 -0800519 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000520
mpagenkofc4f56e2020-11-04 17:17:49 +0000521 var wg sync.WaitGroup
522 wg.Add(1) // for the 1 go routine to finish
Girish Gowdra50e56422021-06-01 16:46:04 -0700523 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpInstancePath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000524 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000525 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000526
Girish Gowdra041dcb32020-11-16 16:54:30 -0800527 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530528}
529
Himani Chawla6d2ae152020-09-02 13:11:20 +0530530func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000531 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530532 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000533
dbainbri4d3a0dc2020-12-02 00:33:42 +0000534 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000535
dbainbri4d3a0dc2020-12-02 00:33:42 +0000536 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000537 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000538 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000539 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
540 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530541 if dh.pOnuTP == nil {
542 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000543 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530544 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000545 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530546 }
547
548 msgBody := msg.GetBody()
549 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
550 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000551 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530552 "device-id": dh.deviceID, "error": err})
553 return err
554 }
555
556 //compare TECH_PROFILE_DOWNLOAD_REQUEST
557 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000558 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000559
560 if delTcontMsg.UniId > 255 {
561 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
562 delTcontMsg.UniId, dh.deviceID))
563 }
564 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700565 tpPath := delTcontMsg.TpInstancePath
Girish Gowdra041dcb32020-11-16 16:54:30 -0800566 tpID, err := GetTpIDFromTpPath(tpPath)
567 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000568 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800569 return err
570 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000571
dbainbri4d3a0dc2020-12-02 00:33:42 +0000572 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700573 pDevEntry.freeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530574 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530575 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530576 dctx, cancel := context.WithDeadline(context.Background(), deadline)
577
Girish Gowdra041dcb32020-11-16 16:54:30 -0800578 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000579 pDevEntry.resetKvProcessingErrorIndication()
580
Himani Chawla26e555c2020-08-31 12:30:20 +0530581 var wg sync.WaitGroup
582 wg.Add(2) // for the 2 go routines to finish
Girish Gowdra50e56422021-06-01 16:46:04 -0700583 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpInstancePath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530584 cResourceTcont, delTcontMsg.AllocId, &wg)
585 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000586 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
587 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000588
Girish Gowdra041dcb32020-11-16 16:54:30 -0800589 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530590 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530591 return nil
592}
593
Himani Chawla6d2ae152020-09-02 13:11:20 +0530594//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000595// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
596// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000597func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000598 msgID := msg.Header.Id
599 msgType := msg.Header.Type
600 fromTopic := msg.Header.FromTopic
601 toTopic := msg.Header.ToTopic
602 toDeviceID := msg.Header.ToDeviceId
603 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000604 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000605 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
606
607 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000608 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000609 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
610 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000611 {
mpagenko057889c2021-01-21 16:51:58 +0000612 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000613 }
mpagenkoaf801632020-07-03 10:00:42 +0000614 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
615 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000616 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000617 }
618 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
619 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000620 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000621
mpagenkoaf801632020-07-03 10:00:42 +0000622 }
623 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
624 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000625 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000626 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000627 default:
628 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000629 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000630 "msgType": msg.Header.Type, "device-id": dh.deviceID})
631 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000632 }
633 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000634}
635
mpagenkodff5dda2020-08-28 11:52:01 +0000636//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000637func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
638 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000639 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
ozgecanetsia82b91a62021-05-21 18:54:49 +0300640 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID, "metadata": apFlowMetaData})
mpagenko01e726e2020-10-23 09:45:29 +0000641 var retError error = nil
642 //Remove flows (always remove flows first - remove old and add new with same cookie may be part of the same request)
mpagenkodff5dda2020-08-28 11:52:01 +0000643 if apOfFlowChanges.ToRemove != nil {
644 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000645 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000646 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000647 "device-id": dh.deviceID})
648 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000649 continue
650 }
651 flowInPort := flow.GetInPort(flowItem)
652 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000653 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000654 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
655 continue
656 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000657 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000658 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000659 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000660 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000661 continue
662 } else {
663 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530664 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000665 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
666 loUniPort = uniPort
667 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000668 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000669 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
670 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
671 flowInPort, dh.deviceID)
672 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000673 }
674 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000675 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000676 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000677 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000678 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000679 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000680 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000681 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000682 log.Fields{"device-id": dh.deviceID, "error": err})
683 retError = err
684 continue
685 //return err
686 } else { // if last setting succeeds, overwrite possibly previously set error
687 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000688 }
689 }
690 }
691 }
mpagenko01e726e2020-10-23 09:45:29 +0000692 if apOfFlowChanges.ToAdd != nil {
693 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
694 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000695 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000696 "device-id": dh.deviceID})
697 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
698 continue
699 }
700 flowInPort := flow.GetInPort(flowItem)
701 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000702 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000703 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
704 continue
705 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
706 } else if flowInPort == dh.ponPortNumber {
707 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000708 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000709 "device-id": dh.deviceID, "inPort": flowInPort})
710 continue
711 } else {
712 // this is the relevant upstream flow
713 var loUniPort *onuUniPort
714 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
715 loUniPort = uniPort
716 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000717 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000718 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
719 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
720 flowInPort, dh.deviceID)
721 continue
722 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
723 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000724 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
725 // if not, we just throw some error here to have an indication about that, if we really need to support that
726 // then we would need to create some means to activate the internal stored flows
727 // after the device gets active automatically (and still with its dependency to the TechProfile)
728 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
729 // also abort for the other still possible flows here
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000730 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000731 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000732 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000733 return fmt.Errorf("improper device state on device %s", dh.deviceID)
734 }
735
mpagenko01e726e2020-10-23 09:45:29 +0000736 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000737 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000738 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
739 "uniPortName": loUniPort.name})
ozgecanetsia82b91a62021-05-21 18:54:49 +0300740 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort, apFlowMetaData)
mpagenko01e726e2020-10-23 09:45:29 +0000741 //try next flow after processing error
742 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000743 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000744 log.Fields{"device-id": dh.deviceID, "error": err})
745 retError = err
746 continue
747 //return err
748 } else { // if last setting succeeds, overwrite possibly previously set error
749 retError = nil
750 }
751 }
752 }
753 }
754 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000755}
756
Himani Chawla6d2ae152020-09-02 13:11:20 +0530757//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000758//following are the expected device states after this activity:
759//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
760// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000761func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
762 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000763
mpagenko900ee4b2020-10-12 11:56:34 +0000764 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000765 //note that disableDevice sequences in some 'ONU active' state may yield also
766 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000767 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000768 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000769 //disable-device shall be just a UNi/ONU-G related admin state setting
770 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000771
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000772 if dh.isReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000773 // disable UNI ports/ONU
774 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
775 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000776 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000777 } else { //LockStateFSM already init
778 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000779 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000780 }
781 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000782 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000783 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000784 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000785 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
786 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000787 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000788 }
mpagenko01e726e2020-10-23 09:45:29 +0000789 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000790
791 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000792 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000793 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300794 }
795}
796
Himani Chawla6d2ae152020-09-02 13:11:20 +0530797//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000798func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
799 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000800
mpagenkoaa3afe92021-05-21 16:20:58 +0000801 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000802 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
803 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
804 // for real ONU's that should have nearly no influence
805 // Note that for real ONU's there is anyway a problematic situation with following sequence:
806 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
807 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
808 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000809 dh.setReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000810
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000811 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000812 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000813 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000814 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000815 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000816 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000817 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000818 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300819}
820
dbainbri4d3a0dc2020-12-02 00:33:42 +0000821func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
822 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000823
dbainbri4d3a0dc2020-12-02 00:33:42 +0000824 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000825 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000826 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000827 return
828 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000829 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000830 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000831 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000832 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000833 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000834 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700835 dh.stopReconciling(ctx, false)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000836 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000837 }
Himani Chawla4d908332020-08-31 12:30:20 +0530838 var onuIndication oop.OnuIndication
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000839 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000840 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
841 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
842 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
843 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000844 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000845 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000846}
847
dbainbri4d3a0dc2020-12-02 00:33:42 +0000848func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
849 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000850
dbainbri4d3a0dc2020-12-02 00:33:42 +0000851 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000852 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000853 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000854 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700855 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000856 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000857 return
858 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000859 dh.pOnuTP.lockTpProcMutex()
860 defer dh.pOnuTP.unlockTpProcMutex()
861
mpagenko2dc896e2021-08-02 12:03:59 +0000862 pDevEntry.mutexPersOnuConfig.RLock()
863 persMutexLock := true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000864 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko2dc896e2021-08-02 12:03:59 +0000865 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000866 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000867 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000868 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700869 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000870 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000871 return
872 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000873 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700874 techProfsFound := false
875 techProfInstLoadFailed := false
876outerLoop:
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000877 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000878 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
879 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000880 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000881 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000882 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000883 }
mpagenko2dc896e2021-08-02 12:03:59 +0000884 //release mutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
885 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
886 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
887 pDevEntry.mutexPersOnuConfig.RUnlock()
888 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700889 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800890 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700891 // Request the TpInstance again from the openolt adapter in case of reconcile
892 iaTechTpInst, err := dh.AdapterProxy.TechProfileInstanceRequest(ctx, uniData.PersTpPathMap[tpID],
893 dh.device.ParentPortNo, dh.device.ProxyAddress.OnuId, uint32(uniData.PersUniID),
894 dh.pOpenOnuAc.config.Topic, dh.ProxyAddressType,
895 dh.parentID, dh.ProxyAddressID)
896 if err != nil || iaTechTpInst == nil {
897 logger.Errorw(ctx, "error fetching tp instance",
898 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID, "err": err})
899 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
900 break outerLoop
901 }
902 var tpInst tech_profile.TechProfileInstance
903 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
904 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
905 tpInst = *techTpInst.TpInstance
mpagenko2dc896e2021-08-02 12:03:59 +0000906 logger.Debugw(ctx, "received-tp-instance-successfully-after-reconcile", log.Fields{
907 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700908 default: // do not support epon or other tech
mpagenko2dc896e2021-08-02 12:03:59 +0000909 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
910 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700911 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
912 break outerLoop
913 }
914
Girish Gowdra041dcb32020-11-16 16:54:30 -0800915 // deadline context to ensure completion of background routines waited for
916 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
917 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000918 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000919
Girish Gowdra041dcb32020-11-16 16:54:30 -0800920 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
921 var wg sync.WaitGroup
922 wg.Add(1) // for the 1 go routine to finish
Girish Gowdra50e56422021-06-01 16:46:04 -0700923 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000924 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800925 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000926 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700927 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
928 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800929 }
mpagenko2dc896e2021-08-02 12:03:59 +0000930 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000931 if len(uniData.PersFlowParams) != 0 {
932 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000933 }
mpagenko2dc896e2021-08-02 12:03:59 +0000934 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
935 persMutexLock = true
936 } // for all UNI entries from sOnuPersistentData
937 if persMutexLock { // if loop was left with mutexPersOnuConfig still set
938 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000939 }
mpagenko2dc896e2021-08-02 12:03:59 +0000940
941 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
942 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
943}
944
945func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
946 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
947 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000948 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
949 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000950 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700951 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000952 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000953 return
954 }
mpagenko2dc896e2021-08-02 12:03:59 +0000955 if abTechProfInstLoadFailed {
Girish Gowdra50e56422021-06-01 16:46:04 -0700956 dh.setDeviceReason(drTechProfileConfigDownloadFailed)
957 dh.stopReconciling(ctx, false)
958 return
959 } else if dh.isSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000960 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
961 }
mpagenko2dc896e2021-08-02 12:03:59 +0000962 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000963 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
964 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000965 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700966 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000967 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000968 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000969}
970
dbainbri4d3a0dc2020-12-02 00:33:42 +0000971func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
972 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000973
dbainbri4d3a0dc2020-12-02 00:33:42 +0000974 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000975 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000976 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000977 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700978 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000979 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000980 return
981 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000982
mpagenko2dc896e2021-08-02 12:03:59 +0000983 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000984 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko2dc896e2021-08-02 12:03:59 +0000985 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000986 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000987 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000988 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700989 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000990 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000991 return
992 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000993 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000994 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000995 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
996 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000997 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000998 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000999 continue
1000 }
1001 if len(uniData.PersTpPathMap) == 0 {
1002 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
1003 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001004 // It doesn't make sense to configure any flows if no TPs are available
1005 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001006 }
mpagenko2dc896e2021-08-02 12:03:59 +00001007 //release mutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1008 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
1009 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1010 pDevEntry.mutexPersOnuConfig.RUnlock()
1011
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001012 var uniPort *onuUniPort
1013 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +00001014 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001015 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001016 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
1017 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001018 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001019 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001020 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001021 return
1022 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001023 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001024 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001025 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001026 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001027 for _, flowData := range uniData.PersFlowParams {
mpagenko2dc896e2021-08-02 12:03:59 +00001028 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1029 "device-id": dh.deviceID, "uni-id": uniData.PersUniID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001030 // If this is the last flow for the device we need to announce it the waiting
1031 // chReconcilingFlowsFinished channel
1032 if flowsProcessed == len(uniData.PersFlowParams)-1 {
1033 lastFlowToReconcile = true
1034 }
mpagenko01e726e2020-10-23 09:45:29 +00001035 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenko7d14de12021-07-27 08:31:56 +00001036 dh.lockVlanConfig.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001037 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001038 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +00001039 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +03001040 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001041 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001042 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001043 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001044 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00001045 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +03001046 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001047 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001048 }
1049 }
mpagenko7d14de12021-07-27 08:31:56 +00001050 dh.lockVlanConfig.Unlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001051 flowsProcessed++
mpagenko2dc896e2021-08-02 12:03:59 +00001052 } //for all flows of this UNI
1053 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
1054 "device-id": dh.deviceID, "uni-id": uniData.PersUniID, "flowsProcessed": flowsProcessed,
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001055 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
1056 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001057 // this can't be used as global finished reconciling flag because
1058 // assumes is getting called before the state machines for the last flow is completed,
1059 // while this is not guaranteed.
1060 //dh.setReconcilingFlows(false)
mpagenko2dc896e2021-08-02 12:03:59 +00001061 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
1062 } // for all UNI entries from sOnuPersistentData
1063 pDevEntry.mutexPersOnuConfig.RUnlock()
1064
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001065 if !flowsFound {
1066 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
1067 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001068 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001069 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001070 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001071 return
1072 }
1073 if dh.isSkipOnuConfigReconciling() {
1074 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001075 }
1076}
1077
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001078func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
1079 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001080 dh.stopReconciling(ctx, true)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001081}
1082
dbainbri4d3a0dc2020-12-02 00:33:42 +00001083func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
1084 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001085
dbainbri4d3a0dc2020-12-02 00:33:42 +00001086 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001087 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001088 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +00001089 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001090 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001091 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001092
1093 // deadline context to ensure completion of background routines waited for
1094 //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 +05301095 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001096 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001097
1098 pDevEntry.resetKvProcessingErrorIndication()
1099
1100 var wg sync.WaitGroup
1101 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001102 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1103 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001104
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001105 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001106 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001107}
1108
mpagenko15ff4a52021-03-02 10:09:20 +00001109//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1110// before this change here return like this was used:
1111// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1112//was and is called in background - error return does not make sense
1113func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1114 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1115 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001116 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001117 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001118 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001119 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301120 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001121 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001122 return
Himani Chawla4d908332020-08-31 12:30:20 +05301123 }
mpagenko01e726e2020-10-23 09:45:29 +00001124
1125 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001126 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001127
dbainbri4d3a0dc2020-12-02 00:33:42 +00001128 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001129 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001130 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001131 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001132 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001133 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001134 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001135 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001136 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001137 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001138 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001139 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001140 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1141 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1142 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1143 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001144}
1145
mpagenkoc8bba412021-01-15 15:38:44 +00001146//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +00001147func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1148 apDownloadManager *adapterDownloadManager) error {
1149 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001150 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001151
1152 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001153 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1154 if pDevEntry == nil {
1155 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1156 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1157 }
1158
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001159 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001160 var inactiveImageID uint16
1161 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1162 dh.lockUpgradeFsm.Lock()
1163 defer dh.lockUpgradeFsm.Unlock()
1164 if dh.pOnuUpradeFsm == nil {
1165 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1166 if err == nil {
1167 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1168 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1169 "device-id": dh.deviceID, "error": err})
1170 }
1171 } else {
1172 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001173 "device-id": dh.deviceID, "error": err})
1174 }
mpagenko15ff4a52021-03-02 10:09:20 +00001175 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1176 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1177 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1178 if pUpgradeStatemachine != nil {
1179 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1180 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1181 "device-id": dh.deviceID, "error": err})
1182 }
1183 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1184 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1185 // for now a second start of download should work again
1186 } else { //should never occur
1187 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1188 "device-id": dh.deviceID})
1189 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001190 }
mpagenko80622a52021-02-09 16:53:23 +00001191 }
mpagenko15ff4a52021-03-02 10:09:20 +00001192 } else {
1193 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1194 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001195 }
1196 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001197 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1198 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001199 }
1200 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001201}
1202
mpagenkoc26d4c02021-05-06 14:27:57 +00001203//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1204// after the OnuImage has been downloaded to the adapter, called in background
1205func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
1206 apDownloadManager *fileDownloadManager, aImageIdentifier string) {
1207
1208 var err error
1209 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1210 if pDevEntry == nil {
1211 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1212 return
1213 }
1214
1215 var inactiveImageID uint16
1216 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1217 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
1218 "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
1219 dh.lockUpgradeFsm.Lock()
1220 defer dh.lockUpgradeFsm.Unlock()
1221 if dh.pOnuUpradeFsm == nil {
1222 //OmciOnuSwUpgradeDone could be used to create some Kafka event with information on upgrade completion,
1223 // but none yet defined
1224 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1225 if err == nil {
1226 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
Holger Hildebrandtac010732021-06-02 13:35:39 +00001227 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00001228 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1229 "device-id": dh.deviceID, "error": err})
1230 return
1231 }
1232 } else {
1233 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1234 "device-id": dh.deviceID, "error": err})
1235 }
1236 return
1237 }
1238 //OnuSw upgrade already running - restart (with possible abort of running)
1239 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1240 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1241 if pUpgradeStatemachine != nil {
1242 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1243 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1244 "device-id": dh.deviceID, "error": err})
1245 return
1246 }
1247 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1248 // for now a second start of download should work again - must still be initiated by user
1249 } else { //should never occur
1250 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1251 "device-id": dh.deviceID})
1252 }
1253 return
1254 }
1255 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1256 "device-id": dh.deviceID, "error": err})
1257}
1258
1259//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001260func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1261 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001262 var err error
1263 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1264 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1265 // 2.) activation of the inactive image
1266
1267 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1268 if pDevEntry == nil {
1269 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001270 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001271 }
1272 dh.lockUpgradeFsm.RLock()
1273 if dh.pOnuUpradeFsm != nil {
1274 dh.lockUpgradeFsm.RUnlock()
1275 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1276 dh.deviceID, dh.deviceID)
1277 if getErr != nil || onuVolthaDevice == nil {
1278 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 +00001279 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001280 }
1281 // use the OnuVendor identification from this device for the internal unique name
1282 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1283 // 1.) check a started upgrade process and rely the activation request to it
1284 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001285 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001286 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1287 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001288 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001289 }
mpagenko183647c2021-06-08 15:25:04 +00001290 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1291 "device-id": dh.deviceID, "image-id": imageIdentifier})
1292 var pImageStates *voltha.ImageState
1293 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1294 pImageStates = &voltha.ImageState{}
1295 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1296 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1297 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1298 }
1299 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001300 } //else
1301 dh.lockUpgradeFsm.RUnlock()
1302
1303 // 2.) check if requested image-version equals the inactive one and start its activation
1304 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1305 var inactiveImageID uint16
1306 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1307 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1308 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
mpagenko183647c2021-06-08 15:25:04 +00001309 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001310 }
1311 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1312 if err == nil {
1313 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1314 inactiveImageID, aCommitRequest); err != nil {
1315 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1316 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001317 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001318 }
1319 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1320 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001321 var pImageStates *voltha.ImageState
1322 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1323 pImageStates := &voltha.ImageState{}
1324 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1325 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1326 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1327 }
1328 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001329 } //else
1330 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1331 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001332 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001333}
1334
1335//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001336func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1337 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001338 var err error
1339 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1340 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1341 // 2.) commitment of the active image
1342
1343 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1344 if pDevEntry == nil {
1345 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001346 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001347 }
1348 dh.lockUpgradeFsm.RLock()
1349 if dh.pOnuUpradeFsm != nil {
1350 dh.lockUpgradeFsm.RUnlock()
1351 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1352 dh.deviceID, dh.deviceID)
1353 if getErr != nil || onuVolthaDevice == nil {
1354 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 +00001355 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001356 }
1357 // use the OnuVendor identification from this device for the internal unique name
1358 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1359 // 1.) check a started upgrade process and rely the commitment request to it
1360 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001361 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001362 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1363 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001364 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001365 }
mpagenko183647c2021-06-08 15:25:04 +00001366 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1367 "device-id": dh.deviceID, "image-id": imageIdentifier})
1368 var pImageStates *voltha.ImageState
1369 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1370 pImageStates := &voltha.ImageState{}
1371 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1372 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1373 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1374 }
1375 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001376 } //else
1377 dh.lockUpgradeFsm.RUnlock()
1378
mpagenko183647c2021-06-08 15:25:04 +00001379 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001380 var activeImageID uint16
1381 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1382 logger.Errorw(ctx, "get active image failed", log.Fields{
1383 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
mpagenko183647c2021-06-08 15:25:04 +00001384 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001385 }
1386 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1387 if err == nil {
1388 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1389 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1390 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001391 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001392 }
1393 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1394 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001395 var pImageStates *voltha.ImageState
1396 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1397 pImageStates := &voltha.ImageState{}
1398 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1399 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1400 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1401 }
1402 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001403 } //else
1404 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1405 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001406 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001407}
1408
mpagenkoaa3afe92021-05-21 16:20:58 +00001409func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
1410 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1411 pDeviceImageState.DeviceId = dh.deviceID
mpagenko183647c2021-06-08 15:25:04 +00001412 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001413 dh.lockUpgradeFsm.RLock()
1414 if dh.pOnuUpradeFsm != nil {
1415 dh.lockUpgradeFsm.RUnlock()
mpagenko183647c2021-06-08 15:25:04 +00001416 if pImageStates, err := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion); err == nil {
mpagenkoaa3afe92021-05-21 16:20:58 +00001417 pDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
1418 pDeviceImageState.ImageState.Reason = pImageStates.Reason
1419 pDeviceImageState.ImageState.ImageState = pImageStates.ImageState
1420 } else {
1421 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1422 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1423 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1424 }
1425 } else {
1426 dh.lockUpgradeFsm.RUnlock()
1427 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1428 if dh.upgradeSuccess {
1429 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
1430 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMITTED
1431 } else {
1432 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1433 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1434 }
1435 }
1436}
1437
1438func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1439 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1440 pDeviceImageState.DeviceId = dh.deviceID
mpagenko7455fd42021-06-10 16:25:55 +00001441 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001442 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1443 dh.lockUpgradeFsm.RLock()
1444 if dh.pOnuUpradeFsm != nil {
1445 dh.lockUpgradeFsm.RUnlock()
1446 //option: it could be also checked if the upgrade FSM is running on the given imageIdentifier or version
1447 // by now just straightforward assume this to be true
1448 dh.pOnuUpradeFsm.CancelProcessing(ctx)
1449 //nolint:misspell
1450 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
1451 //nolint:misspell
1452 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1453 } else {
1454 dh.lockUpgradeFsm.RUnlock()
1455 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1456 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1457 }
1458}
1459
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001460func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1461
1462 var onuImageStatus *OnuImageStatus
1463
1464 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1465 if pDevEntry != nil {
1466 onuImageStatus = NewOnuImageStatus(pDevEntry)
1467 pDevEntry.mutexOnuImageStatus.Lock()
1468 pDevEntry.pOnuImageStatus = onuImageStatus
1469 pDevEntry.mutexOnuImageStatus.Unlock()
1470
1471 } else {
1472 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1473 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1474 }
1475 images, err := onuImageStatus.getOnuImageStatus(ctx)
1476 pDevEntry.mutexOnuImageStatus.Lock()
1477 pDevEntry.pOnuImageStatus = nil
1478 pDevEntry.mutexOnuImageStatus.Unlock()
1479 return images, err
1480}
1481
Himani Chawla6d2ae152020-09-02 13:11:20 +05301482// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001483// #####################################################################################
1484
1485// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301486// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001487
dbainbri4d3a0dc2020-12-02 00:33:42 +00001488func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1489 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 +00001490}
1491
1492// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001493func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001494
dbainbri4d3a0dc2020-12-02 00:33:42 +00001495 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001496 var err error
1497
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001498 // populate what we know. rest comes later after mib sync
1499 dh.device.Root = false
1500 dh.device.Vendor = "OpenONU"
1501 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001502 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001503 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001504
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001505 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001506
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001507 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001508 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1509 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301510 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001511 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001512 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001513 log.Fields{"device-id": dh.deviceID})
1514 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001515
Himani Chawla4d908332020-08-31 12:30:20 +05301516 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001517 dh.ponPortNumber = dh.device.ParentPortNo
1518
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001519 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1520 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1521 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001522 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001523 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301524 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001525
1526 /*
1527 self._pon = PonPort.create(self, self._pon_port_number)
1528 self._pon.add_peer(self.parent_id, self._pon_port_number)
1529 self.logger.debug('adding-pon-port-to-agent',
1530 type=self._pon.get_port().type,
1531 admin_state=self._pon.get_port().admin_state,
1532 oper_status=self._pon.get_port().oper_status,
1533 )
1534 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001535 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001536 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001537 var ponPortNo uint32 = 1
1538 if dh.ponPortNumber != 0 {
1539 ponPortNo = dh.ponPortNumber
1540 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001541
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001542 pPonPort := &voltha.Port{
1543 PortNo: ponPortNo,
1544 Label: fmt.Sprintf("pon-%d", ponPortNo),
1545 Type: voltha.Port_PON_ONU,
1546 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301547 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001548 PortNo: ponPortNo}}, // Peer port is parent's port number
1549 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001550 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1551 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001552 e.Cancel(err)
1553 return
1554 }
1555 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001556 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001557 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001558 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001559}
1560
1561// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001562func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001563
dbainbri4d3a0dc2020-12-02 00:33:42 +00001564 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001565 var err error
1566 /*
1567 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1568 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1569 return nil
1570 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001571 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1572 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001573 e.Cancel(err)
1574 return
1575 }
1576
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001577 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001578 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001579 // reconcilement will be continued after mib download is done
1580 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001581
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001582 /*
1583 ############################################################################
1584 # Setup Alarm handler
1585 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1586 device.serial_number)
1587 ############################################################################
1588 # Setup PM configuration for this device
1589 # Pass in ONU specific options
1590 kwargs = {
1591 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1592 'heartbeat': self.heartbeat,
1593 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1594 }
1595 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1596 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1597 self.logical_device_id, device.serial_number,
1598 grouped=True, freq_override=False, **kwargs)
1599 pm_config = self._pm_metrics.make_proto()
1600 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1601 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1602 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1603
1604 # Note, ONU ID and UNI intf set in add_uni_port method
1605 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1606 ani_ports=[self._pon])
1607
1608 # Code to Run OMCI Test Action
1609 kwargs_omci_test_action = {
1610 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1611 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1612 }
1613 serial_number = device.serial_number
1614 self._test_request = OmciTestRequest(self.core_proxy,
1615 self.omci_agent, self.device_id,
1616 AniG, serial_number,
1617 self.logical_device_id,
1618 exclusive=False,
1619 **kwargs_omci_test_action)
1620
1621 self.enabled = True
1622 else:
1623 self.logger.info('onu-already-activated')
1624 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001625
dbainbri4d3a0dc2020-12-02 00:33:42 +00001626 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001627}
1628
1629// doStateConnected get the device info and update to voltha core
1630// for comparison of the original method (not that easy to uncomment): compare here:
1631// voltha-openolt-adapter/adaptercore/device_handler.go
1632// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001633func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001634
dbainbri4d3a0dc2020-12-02 00:33:42 +00001635 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301636 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001637 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001638 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001639}
1640
1641// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001642func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001643
dbainbri4d3a0dc2020-12-02 00:33:42 +00001644 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301645 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001646 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001648
1649 /*
1650 // Synchronous call to update device state - this method is run in its own go routine
1651 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1652 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001653 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 +00001654 return err
1655 }
1656 return nil
1657 */
1658}
1659
1660// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001661func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001662
dbainbri4d3a0dc2020-12-02 00:33:42 +00001663 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001664 var err error
1665
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001666 device := dh.device
1667 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001668 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001669 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001670 e.Cancel(err)
1671 return
1672 }
1673
1674 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001675 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001676 /*
1677 // Update the all ports state on that device to disable
1678 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001679 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001680 return er
1681 }
1682
1683 //Update the device oper state and connection status
1684 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1685 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1686 dh.device = cloned
1687
1688 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001689 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001690 return er
1691 }
1692
1693 //get the child device for the parent device
1694 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1695 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001696 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001697 return err
1698 }
1699 for _, onuDevice := range onuDevices.Items {
1700
1701 // Update onu state as down in onu adapter
1702 onuInd := oop.OnuIndication{}
1703 onuInd.OperState = "down"
1704 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1705 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1706 if er != nil {
1707 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001708 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001709 //Do not return here and continue to process other ONUs
1710 }
1711 }
1712 // * Discovered ONUs entries need to be cleared , since after OLT
1713 // is up, it starts sending discovery indications again* /
1714 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001715 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001716 return nil
1717 */
Himani Chawla4d908332020-08-31 12:30:20 +05301718 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001719 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001720 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001721}
1722
Himani Chawla6d2ae152020-09-02 13:11:20 +05301723// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001724// #################################################################################
1725
1726// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301727// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001728
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001729//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001730func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001731 dh.lockDevice.RLock()
1732 pOnuDeviceEntry := dh.pOnuOmciDevice
1733 if aWait && pOnuDeviceEntry == nil {
1734 //keep the read sema short to allow for subsequent write
1735 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001736 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001737 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1738 // so it might be needed to wait here for that event with some timeout
1739 select {
1740 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001742 return nil
1743 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001744 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001745 // if written now, we can return the written value without sema
1746 return dh.pOnuOmciDevice
1747 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001748 }
mpagenko3af1f032020-06-10 08:53:41 +00001749 dh.lockDevice.RUnlock()
1750 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001751}
1752
Himani Chawla6d2ae152020-09-02 13:11:20 +05301753//setOnuDeviceEntry sets the ONU device entry within the handler
1754func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001755 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001756 dh.lockDevice.Lock()
1757 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001758 dh.pOnuOmciDevice = apDeviceEntry
1759 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001760 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301761 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001762 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001763}
1764
Himani Chawla6d2ae152020-09-02 13:11:20 +05301765//addOnuDeviceEntry creates a new ONU device or returns the existing
1766func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001767 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001768
dbainbri4d3a0dc2020-12-02 00:33:42 +00001769 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001770 if deviceEntry == nil {
1771 /* costum_me_map in python code seems always to be None,
1772 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1773 /* also no 'clock' argument - usage open ...*/
1774 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001775 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001776 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001777 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301778 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001779 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001780 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001781 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001782 // fire deviceEntry ready event to spread to possibly waiting processing
1783 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001784 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001785 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001786 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001787 }
1788 // might be updated with some error handling !!!
1789 return nil
1790}
1791
dbainbri4d3a0dc2020-12-02 00:33:42 +00001792func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1793 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001794 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1795
1796 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001797
dbainbri4d3a0dc2020-12-02 00:33:42 +00001798 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001799 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001800 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001801 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1802 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001803 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001804 if err := dh.storePersistentData(ctx); err != nil {
1805 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001806 log.Fields{"device-id": dh.deviceID, "err": err})
1807 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001808 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001809 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001810 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001811 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1812 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001813 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001814 }
1815 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001816 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001817 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001818
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001819 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001820 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001821 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001822 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 +00001823 log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001824 dh.stopReconciling(ctx, true)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001825 } else {
1826 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001827 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001828 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001829 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1830 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1831 // 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 +00001832 // 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 +00001833 // so let's just try to keep it simple ...
1834 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001835 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001836 if err != nil || device == nil {
1837 //TODO: needs to handle error scenarios
1838 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1839 return errors.New("Voltha Device not found")
1840 }
1841 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001842
dbainbri4d3a0dc2020-12-02 00:33:42 +00001843 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001844 return err
mpagenko3af1f032020-06-10 08:53:41 +00001845 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001846
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001847 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001848
1849 /* this might be a good time for Omci Verify message? */
1850 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001851 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001852 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001853 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001854 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001855
1856 /* give the handler some time here to wait for the OMCi verification result
1857 after Timeout start and try MibUpload FSM anyway
1858 (to prevent stopping on just not supported OMCI verification from ONU) */
1859 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001860 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001861 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001862 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001863 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001864 }
1865
1866 /* In py code it looks earlier (on activate ..)
1867 # Code to Run OMCI Test Action
1868 kwargs_omci_test_action = {
1869 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1870 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1871 }
1872 serial_number = device.serial_number
1873 self._test_request = OmciTestRequest(self.core_proxy,
1874 self.omci_agent, self.device_id,
1875 AniG, serial_number,
1876 self.logical_device_id,
1877 exclusive=False,
1878 **kwargs_omci_test_action)
1879 ...
1880 # Start test requests after a brief pause
1881 if not self._test_request_started:
1882 self._test_request_started = True
1883 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1884 reactor.callLater(tststart, self._test_request.start_collector)
1885
1886 */
1887 /* which is then: in omci_test_request.py : */
1888 /*
1889 def start_collector(self, callback=None):
1890 """
1891 Start the collection loop for an adapter if the frequency > 0
1892
1893 :param callback: (callable) Function to call to collect PM data
1894 """
1895 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1896 if callback is None:
1897 callback = self.perform_test_omci
1898
1899 if self.lc is None:
1900 self.lc = LoopingCall(callback)
1901
1902 if self.default_freq > 0:
1903 self.lc.start(interval=self.default_freq / 10)
1904
1905 def perform_test_omci(self):
1906 """
1907 Perform the initial test request
1908 """
1909 ani_g_entities = self._device.configuration.ani_g_entities
1910 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1911 is not None else None
1912 self._entity_id = ani_g_entities_ids[0]
1913 self.logger.info('perform-test', entity_class=self._entity_class,
1914 entity_id=self._entity_id)
1915 try:
1916 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1917 result = yield self._device.omci_cc.send(frame)
1918 if not result.fields['omci_message'].fields['success_code']:
1919 self.logger.info('Self-Test Submitted Successfully',
1920 code=result.fields[
1921 'omci_message'].fields['success_code'])
1922 else:
1923 raise TestFailure('Test Failure: {}'.format(
1924 result.fields['omci_message'].fields['success_code']))
1925 except TimeoutError as e:
1926 self.deferred.errback(failure.Failure(e))
1927
1928 except Exception as e:
1929 self.logger.exception('perform-test-Error', e=e,
1930 class_id=self._entity_class,
1931 entity_id=self._entity_id)
1932 self.deferred.errback(failure.Failure(e))
1933
1934 */
1935
1936 // PM related heartbeat??? !!!TODO....
1937 //self._heartbeat.enabled = True
1938
mpagenko1cc3cb42020-07-27 15:24:38 +00001939 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1940 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1941 * 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 +05301942 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001943 */
1944 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001945 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001946 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001947 if pMibUlFsm.Is(ulStDisabled) {
1948 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001949 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 +00001950 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301951 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001952 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301953 //Determine ONU status and start/re-start MIB Synchronization tasks
1954 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001955 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301956 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001957 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 +00001958 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001959 }
Himani Chawla4d908332020-08-31 12:30:20 +05301960 } else {
1961 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001962 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 +00001963 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301964 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001965 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001966 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001967 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001968 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001969 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001970 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001971 }
1972 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001974 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001975 }
1976 return nil
1977}
1978
dbainbri4d3a0dc2020-12-02 00:33:42 +00001979func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001980 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001981 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001982 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001983 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001984
mpagenko900ee4b2020-10-12 11:56:34 +00001985 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1986 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1987 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001988 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001989 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001990 log.Fields{"device-id": dh.deviceID, "error": err})
1991 // abort: system behavior is just unstable ...
1992 return err
1993 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001994 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001995 _ = 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 +00001996
1997 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1998 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1999 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00002000 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002001 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002002 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002003 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002004 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002005 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002006
2007 //TODO!!! remove existing traffic profiles
2008 /* from py code, if TP's exist, remove them - not yet implemented
2009 self._tp = dict()
2010 # Let TP download happen again
2011 for uni_id in self._tp_service_specific_task:
2012 self._tp_service_specific_task[uni_id].clear()
2013 for uni_id in self._tech_profile_download_done:
2014 self._tech_profile_download_done[uni_id].clear()
2015 */
2016
dbainbri4d3a0dc2020-12-02 00:33:42 +00002017 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002018
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002019 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002021 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002022 // abort: system behavior is just unstable ...
2023 return err
2024 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002025 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002026 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002027 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00002028 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002029 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002030 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00002031 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002032 // abort: system behavior is just unstable ...
2033 return err
2034 }
2035 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002036 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002037 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002038 return nil
2039}
2040
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002041func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002042 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2043 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2044 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2045 // and using the stop/reset event should never harm
2046
dbainbri4d3a0dc2020-12-02 00:33:42 +00002047 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002048 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002049 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002050 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2051 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002052 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002053 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002054 }
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002055 pDevEntry.mutexOnuImageStatus.RLock()
2056 if pDevEntry.pOnuImageStatus != nil {
2057 pDevEntry.pOnuImageStatus.CancelProcessing(ctx)
2058 }
2059 pDevEntry.mutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002060
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002061 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002062 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002063 }
2064 //MibDownload may run
2065 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2066 if pMibDlFsm != nil {
2067 _ = pMibDlFsm.Event(dlEvReset)
2068 }
2069 //port lock/unlock FSM's may be active
2070 if dh.pUnlockStateFsm != nil {
2071 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2072 }
2073 if dh.pLockStateFsm != nil {
2074 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2075 }
2076 //techProfile related PonAniConfigFsm FSM may be active
2077 if dh.pOnuTP != nil {
2078 // should always be the case here
2079 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
2080 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08002081 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00002082 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002083 }
mpagenko900ee4b2020-10-12 11:56:34 +00002084 }
2085 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002086 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002087 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00002088 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
2089 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002090 dh.lockVlanConfig.RUnlock()
2091 //reset of all Fsm is always accompanied by global persistency data removal
2092 // no need to remove specific data
2093 pVlanFilterFsm.RequestClearPersistency(false)
2094 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002095 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002096 } else {
2097 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002098 }
2099 }
2100 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002101 if dh.getCollectorIsRunning() {
2102 // Stop collector routine
2103 dh.stopCollector <- true
2104 }
Himani Chawla1472c682021-03-17 17:11:14 +05302105 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302106 dh.stopAlarmManager <- true
2107 }
2108
mpagenko80622a52021-02-09 16:53:23 +00002109 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00002110 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002111 dh.lockUpgradeFsm.RLock()
2112 if dh.pOnuUpradeFsm != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00002113 dh.pOnuUpradeFsm.CancelProcessing(ctx)
mpagenko80622a52021-02-09 16:53:23 +00002114 }
2115 dh.lockUpgradeFsm.RUnlock()
2116
mpagenko7d6bb022021-03-11 15:07:55 +00002117 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002118 return nil
2119}
2120
dbainbri4d3a0dc2020-12-02 00:33:42 +00002121func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2122 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 +05302123
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002124 // store persistent data collected during MIB upload processing
2125 if err := dh.storePersistentData(ctx); err != nil {
2126 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2127 log.Fields{"device-id": dh.deviceID, "err": err})
2128 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002129 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002130 dh.addAllUniPorts(ctx)
2131
mpagenkoa40e99a2020-11-17 13:50:39 +00002132 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2133 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2134 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2135 * disable/enable toggling here to allow traffic
2136 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2137 * like the py comment says:
2138 * # start by locking all the unis till mib sync and initial mib is downloaded
2139 * # this way we can capture the port down/up events when we are ready
2140 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302141
mpagenkoa40e99a2020-11-17 13:50:39 +00002142 // Init Uni Ports to Admin locked state
2143 // *** should generate UniLockStateDone event *****
2144 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002145 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002146 } else { //LockStateFSM already init
2147 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002148 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002149 }
2150}
2151
dbainbri4d3a0dc2020-12-02 00:33:42 +00002152func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2153 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302154 /* Mib download procedure -
2155 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2156 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002157 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002158 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002159 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002160 return
2161 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302162 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2163 if pMibDlFsm != nil {
2164 if pMibDlFsm.Is(dlStDisabled) {
2165 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002166 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 +05302167 // maybe try a FSM reset and then again ... - TODO!!!
2168 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002169 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302170 // maybe use more specific states here for the specific download steps ...
2171 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002172 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302173 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002174 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302175 //Begin MIB data download (running autonomously)
2176 }
2177 }
2178 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002179 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002180 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302181 // maybe try a FSM reset and then again ... - TODO!!!
2182 }
2183 /***** Mib download started */
2184 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002185 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302186 }
2187}
2188
dbainbri4d3a0dc2020-12-02 00:33:42 +00002189func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2190 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302191 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002192 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002193 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002194 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002195 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2196 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2197 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2198 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002199 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302200 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
2201 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002202 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302203 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002204 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302205 }
2206 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002207 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302208 log.Fields{"device-id": dh.deviceID})
2209 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002210 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002211
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002212 if !dh.getCollectorIsRunning() {
2213 // Start PM collector routine
2214 go dh.startCollector(ctx)
2215 }
2216 if !dh.getAlarmManagerIsRunning(ctx) {
2217 go dh.startAlarmManager(ctx)
2218 }
2219
Girish Gowdrae0140f02021-02-02 16:55:09 -08002220 // Initialize classical L2 PM Interval Counters
2221 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2222 // There is no way we should be landing here, but if we do then
2223 // there is nothing much we can do about this other than log error
2224 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2225 }
2226
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002227 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002228
2229 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2230 if pDevEntry == nil {
2231 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2232 return
2233 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002234 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002235 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002236 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002237 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2238 log.Fields{"device-id": dh.deviceID})
2239 go dh.reconcileDeviceTechProf(ctx)
2240 // reconcilement will be continued after ani config is done
2241 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002242 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002243 // *** should generate UniUnlockStateDone event *****
2244 if dh.pUnlockStateFsm == nil {
2245 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2246 } else { //UnlockStateFSM already init
2247 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2248 dh.runUniLockFsm(ctx, false)
2249 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302250 }
2251}
2252
dbainbri4d3a0dc2020-12-02 00:33:42 +00002253func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2254 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302255
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002256 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002257 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002258 raisedTs := time.Now().Unix()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002259 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2260 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002261 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002262 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002263 return
2264 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002265 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002266 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002267 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002268 if err := dh.storePersistentData(ctx); err != nil {
2269 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002270 log.Fields{"device-id": dh.deviceID, "err": err})
2271 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302272 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002273 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 +05302274 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002275 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002276 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302277 }
2278}
2279
dbainbri4d3a0dc2020-12-02 00:33:42 +00002280func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2281 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002282 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002283 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00002284 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
2285 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002286 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002287 }
2288
dbainbri4d3a0dc2020-12-02 00:33:42 +00002289 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002290 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002291 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002292
2293 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002294 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002295
dbainbri4d3a0dc2020-12-02 00:33:42 +00002296 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002297 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002298 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002299 return
2300 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002301 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002302 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002303 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002304 if err := dh.storePersistentData(ctx); err != nil {
2305 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002306 log.Fields{"device-id": dh.deviceID, "err": err})
2307 }
mpagenko900ee4b2020-10-12 11:56:34 +00002308}
2309
dbainbri4d3a0dc2020-12-02 00:33:42 +00002310func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2311 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002312 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002313 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002314 voltha.OperStatus_ACTIVE); err != nil {
2315 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002316 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002317 }
2318
dbainbri4d3a0dc2020-12-02 00:33:42 +00002319 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002320 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002321 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002322 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002323
2324 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002325 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002326
dbainbri4d3a0dc2020-12-02 00:33:42 +00002327 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002328 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002329 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002330 return
2331 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002332 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002333 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002334 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002335 if err := dh.storePersistentData(ctx); err != nil {
2336 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002337 log.Fields{"device-id": dh.deviceID, "err": err})
2338 }
mpagenko900ee4b2020-10-12 11:56:34 +00002339}
2340
dbainbri4d3a0dc2020-12-02 00:33:42 +00002341func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002342 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002343 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002344 // attention: the device reason update is done based on ONU-UNI-Port related activity
2345 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002346 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002347 // 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 +00002348 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302349 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002350 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002351 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002352 }
2353 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002354 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002355 // attention: the device reason update is done based on ONU-UNI-Port related activity
2356 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002357 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002358 // 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 +00002359 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002360 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002361 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302362}
2363
dbainbri4d3a0dc2020-12-02 00:33:42 +00002364func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2365 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002366 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302367 // attention: the device reason update is done based on ONU-UNI-Port related activity
2368 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302369
mpagenkof1fc3862021-02-16 10:09:52 +00002370 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002371 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002372 // which may be the case from some previous actvity on another UNI Port of the ONU
2373 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002374 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2375 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002376 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002377 }
2378 }
2379 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002380 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002381 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002382 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002383 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302384 }
mpagenkof1fc3862021-02-16 10:09:52 +00002385
2386 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2387 //events that request KvStore write
2388 if err := dh.storePersistentData(ctx); err != nil {
2389 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2390 log.Fields{"device-id": dh.deviceID, "err": err})
2391 }
2392 } else {
2393 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2394 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002395 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302396}
2397
Himani Chawla6d2ae152020-09-02 13:11:20 +05302398//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002399func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302400 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002401 case MibDatabaseSync:
2402 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002403 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002404 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002405 case UniLockStateDone:
2406 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002407 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002408 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002409 case MibDownloadDone:
2410 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002411 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002412 }
2413 case UniUnlockStateDone:
2414 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002415 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002416 }
mpagenko900ee4b2020-10-12 11:56:34 +00002417 case UniEnableStateDone:
2418 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002419 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002420 }
2421 case UniDisableStateDone:
2422 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002423 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002424 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002425 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002426 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002427 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002428 }
mpagenkof1fc3862021-02-16 10:09:52 +00002429 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002430 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002431 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002432 }
mpagenkoaa3afe92021-05-21 16:20:58 +00002433 case OmciOnuSwUpgradeDone:
2434 {
2435 dh.upgradeSuccess = true
2436 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002437 default:
2438 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002439 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002440 }
2441 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002442}
2443
dbainbri4d3a0dc2020-12-02 00:33:42 +00002444func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002445 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002446 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302447 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002448 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002449 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002450 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302451 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002452 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002453 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002454 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002455 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002456 //store UniPort with the System-PortNumber key
2457 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002458 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002459 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002460 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2461 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002462 } //error logging already within UniPort method
2463 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002464 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002465 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002466 }
2467 }
2468}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002469
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002470func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2471 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2472 if pDevEntry == nil {
2473 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2474 return
2475 }
2476 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2477 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2478 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2479 for _, mgmtEntityID := range pptpInstKeys {
2480 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2481 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2482 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2483 i++
2484 }
2485 } else {
2486 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2487 }
2488 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2489 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2490 for _, mgmtEntityID := range veipInstKeys {
2491 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2492 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2493 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2494 i++
2495 }
2496 } else {
2497 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2498 }
2499 if i == 0 {
2500 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2501 }
2502}
2503
mpagenko3af1f032020-06-10 08:53:41 +00002504// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002505func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002506 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302507 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002508 // with following remark:
2509 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2510 // # load on the core
2511
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002512 // 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 +00002513
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002514 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002515 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002516 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002517 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302518 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002519 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002520 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002521 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 +00002522 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002523 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002524 }
mpagenko3af1f032020-06-10 08:53:41 +00002525 }
2526 }
2527}
2528
2529// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002530func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002531 // compare enableUniPortStateUpdate() above
2532 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2533 for uniNo, uniPort := range dh.uniEntityMap {
2534 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002535
2536 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002537 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302538 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002539 if !dh.isReconciling() {
2540 //maybe also use getter functions on uniPort - perhaps later ...
2541 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2542 } else {
2543 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2544 }
2545
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002546 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002547 }
2548}
2549
2550// ONU_Active/Inactive announcement on system KAFKA bus
2551// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002552func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002553 var de voltha.DeviceEvent
2554 eventContext := make(map[string]string)
2555 //Populating event context
2556 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002557 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002558 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002559 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302560 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002561 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 +00002562 }
2563 oltSerialNumber := parentDevice.SerialNumber
2564
2565 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2566 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2567 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302568 eventContext["olt-serial-number"] = oltSerialNumber
2569 eventContext["device-id"] = aDeviceID
2570 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002571 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
2572 if deviceEntry := dh.getOnuDeviceEntry(ctx, false); deviceEntry != nil {
2573 deviceEntry.mutexPersOnuConfig.RLock()
2574 eventContext["equipment-id"] = deviceEntry.sOnuPersistentData.PersEquipmentID
2575 deviceEntry.mutexPersOnuConfig.RUnlock()
2576 eventContext["software-version"] = deviceEntry.getActiveImageVersion(ctx)
2577 deviceEntry.mutexPersOnuConfig.RLock()
2578 eventContext["vendor"] = deviceEntry.sOnuPersistentData.PersVendorID
2579 deviceEntry.mutexPersOnuConfig.RUnlock()
2580 eventContext["inactive-software-version"] = deviceEntry.getInactiveImageVersion(ctx)
2581 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2582 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2583 } else {
2584 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2585 log.Fields{"device-id": aDeviceID})
2586 return
2587 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002588
2589 /* Populating device event body */
2590 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302591 de.ResourceId = aDeviceID
2592 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002593 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2594 de.Description = fmt.Sprintf("%s Event - %s - %s",
2595 cEventObjectType, cOnuActivatedEvent, "Raised")
2596 } else {
2597 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2598 de.Description = fmt.Sprintf("%s Event - %s - %s",
2599 cEventObjectType, cOnuActivatedEvent, "Cleared")
2600 }
2601 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002602 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2603 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302604 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002605 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002606 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302607 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002608}
2609
Himani Chawla4d908332020-08-31 12:30:20 +05302610// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002611func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002612 chLSFsm := make(chan Message, 2048)
2613 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302614 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002615 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002616 sFsmName = "LockStateFSM"
2617 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002618 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002619 sFsmName = "UnLockStateFSM"
2620 }
mpagenko3af1f032020-06-10 08:53:41 +00002621
dbainbri4d3a0dc2020-12-02 00:33:42 +00002622 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002623 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002624 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002625 return
2626 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002627 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002628 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002629 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302630 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002631 dh.pLockStateFsm = pLSFsm
2632 } else {
2633 dh.pUnlockStateFsm = pLSFsm
2634 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002635 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002636 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002637 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002638 }
2639}
2640
2641// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002642func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002643 /* Uni Port lock/unlock procedure -
2644 ***** should run via 'adminDone' state and generate the argument requested event *****
2645 */
2646 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302647 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002648 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2649 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2650 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002651 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302652 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002653 }
2654 } else {
2655 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2656 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2657 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002658 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302659 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002660 }
2661 }
2662 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002663 if pLSStatemachine.Is(uniStDisabled) {
2664 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002665 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002666 // maybe try a FSM reset and then again ... - TODO!!!
2667 } else {
2668 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002669 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002670 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002671 }
2672 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002673 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002674 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002675 // maybe try a FSM reset and then again ... - TODO!!!
2676 }
2677 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002678 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002679 // maybe try a FSM reset and then again ... - TODO!!!
2680 }
2681}
2682
mpagenko80622a52021-02-09 16:53:23 +00002683// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002684func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002685 //in here lockUpgradeFsm is already locked
2686 chUpgradeFsm := make(chan Message, 2048)
2687 var sFsmName = "OnuSwUpgradeFSM"
2688 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002689 if apDevEntry.PDevOmciCC == nil {
2690 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2691 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002692 }
mpagenko15ff4a52021-03-02 10:09:20 +00002693 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002694 sFsmName, chUpgradeFsm)
2695 if dh.pOnuUpradeFsm != nil {
2696 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2697 if pUpgradeStatemachine != nil {
2698 if pUpgradeStatemachine.Is(upgradeStDisabled) {
mpagenkoaa3afe92021-05-21 16:20:58 +00002699 dh.upgradeSuccess = false //for start of upgrade processing reset the last indication
mpagenko80622a52021-02-09 16:53:23 +00002700 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2701 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2702 // maybe try a FSM reset and then again ... - TODO!!!
2703 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2704 }
2705 /***** LockStateFSM started */
2706 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2707 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2708 } else {
2709 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2710 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2711 // maybe try a FSM reset and then again ... - TODO!!!
2712 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2713 }
2714 } else {
2715 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2716 // maybe try a FSM reset and then again ... - TODO!!!
2717 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2718 }
2719 } else {
2720 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2721 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2722 }
2723 return nil
2724}
2725
2726// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2727func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2728 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2729 "device-id": dh.deviceID})
2730 dh.lockUpgradeFsm.Lock()
2731 defer dh.lockUpgradeFsm.Unlock()
2732 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2733}
2734
mpagenko15ff4a52021-03-02 10:09:20 +00002735// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2736func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2737 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2738 if pDevEntry == nil {
2739 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2740 return
2741 }
2742
2743 dh.lockUpgradeFsm.RLock()
2744 defer dh.lockUpgradeFsm.RUnlock()
2745 if dh.pOnuUpradeFsm != nil {
2746 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2747 if pUpgradeStatemachine != nil {
2748 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2749 // (some manual forced commit could do without)
mpagenko1f8e8822021-06-25 14:10:21 +00002750 upgradeState := pUpgradeStatemachine.Current()
2751 if (upgradeState == upgradeStWaitForCommit) ||
2752 (upgradeState == upgradeStRequestingActivate) {
2753 // also include upgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00002754 // 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 +00002755 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00002756 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
2757 if errImg != nil {
2758 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
2759 log.Fields{"device-id": dh.deviceID})
2760 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
mpagenko15ff4a52021-03-02 10:09:20 +00002761 return
2762 }
mpagenko1f8e8822021-06-25 14:10:21 +00002763 if activeImageID == dh.pOnuUpradeFsm.inactiveImageMeID {
2764 if (upgradeState == upgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
2765 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
2766 if err := pUpgradeStatemachine.Event(upgradeEvActivationDone); err != nil {
2767 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
2768 return
2769 }
2770 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
2771 "state": upgradeState, "device-id": dh.deviceID})
2772 } else {
2773 //FSM in waitForCommit or (upgradeStRequestingActivate [lost ActivateResp] and commit allowed)
2774 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2775 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2776 return
2777 }
2778 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2779 "state": upgradeState, "device-id": dh.deviceID})
2780 }
2781 } else {
2782 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit/on ActivateResponse, but load did not start with expected image Id",
2783 log.Fields{"device-id": dh.deviceID})
2784 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2785 return
2786 }
mpagenko15ff4a52021-03-02 10:09:20 +00002787 } else {
2788 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2789 log.Fields{"device-id": dh.deviceID})
2790 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2791 return
2792 }
mpagenko183647c2021-06-08 15:25:04 +00002793 } else {
2794 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2795 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2796 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2797 if dh.pOnuUpradeFsm.inactiveImageMeID == activeImageID {
2798 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2799 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2800 dh.pOnuUpradeFsm.SetImageState(ctx, voltha.ImageState_IMAGE_ACTIVE)
2801 }
2802 }
mpagenko15ff4a52021-03-02 10:09:20 +00002803 }
2804 }
2805 } else {
2806 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2807 }
2808}
2809
Himani Chawla6d2ae152020-09-02 13:11:20 +05302810//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002811func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002812
2813 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002814 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07002815 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00002816 kvbackend := &db.Backend{
2817 Client: dh.pOpenOnuAc.kvClient,
2818 StoreType: dh.pOpenOnuAc.KVStoreType,
2819 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002820 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002821 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2822 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002823
mpagenkoaf801632020-07-03 10:00:42 +00002824 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002825}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002826func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302827 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002828
mpagenkodff5dda2020-08-28 11:52:01 +00002829 for _, field := range flow.GetOfbFields(apFlowItem) {
2830 switch field.Type {
2831 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2832 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002833 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002834 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2835 }
mpagenko01e726e2020-10-23 09:45:29 +00002836 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002837 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2838 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302839 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002840 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302841 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2842 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002843 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2844 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002845 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2846 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302847 return
mpagenkodff5dda2020-08-28 11:52:01 +00002848 }
2849 }
mpagenko01e726e2020-10-23 09:45:29 +00002850 */
mpagenkodff5dda2020-08-28 11:52:01 +00002851 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2852 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302853 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002854 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302855 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002856 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302857 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002858 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002859 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302860 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002861 }
2862 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2863 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302864 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002865 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002866 "PCP": loAddPcp})
2867 }
2868 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2869 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002870 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002871 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2872 }
2873 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2874 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002875 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002876 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2877 }
2878 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2879 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002880 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002881 "IPv4-DST": field.GetIpv4Dst()})
2882 }
2883 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2884 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002885 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002886 "IPv4-SRC": field.GetIpv4Src()})
2887 }
2888 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2889 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002890 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002891 "Metadata": field.GetTableMetadata()})
2892 }
2893 /*
2894 default:
2895 {
2896 //all other entires ignored
2897 }
2898 */
2899 }
2900 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302901}
mpagenkodff5dda2020-08-28 11:52:01 +00002902
dbainbri4d3a0dc2020-12-02 00:33:42 +00002903func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002904 for _, action := range flow.GetActions(apFlowItem) {
2905 switch action.Type {
2906 /* not used:
2907 case of.OfpActionType_OFPAT_OUTPUT:
2908 {
mpagenko01e726e2020-10-23 09:45:29 +00002909 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002910 "Output": action.GetOutput()})
2911 }
2912 */
2913 case of.OfpActionType_OFPAT_PUSH_VLAN:
2914 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002915 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002916 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2917 }
2918 case of.OfpActionType_OFPAT_SET_FIELD:
2919 {
2920 pActionSetField := action.GetSetField()
2921 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002922 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002923 "OxcmClass": pActionSetField.Field.OxmClass})
2924 }
2925 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302926 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002927 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302928 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002929 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302930 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002931 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302932 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002933 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002934 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002935 "Type": pActionSetField.Field.GetOfbField().Type})
2936 }
2937 }
2938 /*
2939 default:
2940 {
2941 //all other entires ignored
2942 }
2943 */
2944 }
2945 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302946}
2947
2948//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
ozgecanetsia82b91a62021-05-21 18:54:49 +03002949func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort,
2950 apFlowMetaData *voltha.FlowMetadata) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302951 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2952 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2953 var loAddPcp, loSetPcp uint8
2954 var loIPProto uint32
2955 /* the TechProfileId is part of the flow Metadata - compare also comment within
2956 * OLT-Adapter:openolt_flowmgr.go
2957 * Metadata 8 bytes:
2958 * Most Significant 2 Bytes = Inner VLAN
2959 * Next 2 Bytes = Tech Profile ID(TPID)
2960 * Least Significant 4 Bytes = Port ID
2961 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2962 * subscriber related flows.
2963 */
2964
dbainbri4d3a0dc2020-12-02 00:33:42 +00002965 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302966 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002967 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302968 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002969 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302970 }
mpagenko551a4d42020-12-08 18:09:20 +00002971 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002972 loCookie := apFlowItem.GetCookie()
2973 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002974 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002975 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302976
dbainbri4d3a0dc2020-12-02 00:33:42 +00002977 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002978 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302979 if loIPProto == 2 {
2980 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2981 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002982 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2983 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302984 return nil
2985 }
mpagenko01e726e2020-10-23 09:45:29 +00002986 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002987 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002988
2989 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002990 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002991 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2992 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2993 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2994 //TODO!!: Use DeviceId within the error response to rwCore
2995 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002996 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002997 }
2998 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002999 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003000 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3001 } else {
3002 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3003 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3004 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303005 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003006 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003007 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003008 }
mpagenko9a304ea2020-12-16 15:54:01 +00003009
3010 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenko7d14de12021-07-27 08:31:56 +00003011 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3012 // when different rules are requested concurrently for the same uni
3013 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3014 dh.lockVlanConfig.Lock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003015 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID, "tpID": loTpID, "uniID": apUniPort.uniID})
3016 var meter *voltha.OfpMeterConfig
3017 if apFlowMetaData != nil {
3018 meter = apFlowMetaData.Meters[0]
3019 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303020 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003021 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003022 loMatchVlan, loSetVlan, loSetPcp, false, meter)
mpagenko7d14de12021-07-27 08:31:56 +00003023 dh.lockVlanConfig.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +00003024 return err
mpagenkodff5dda2020-08-28 11:52:01 +00003025 }
mpagenko7d14de12021-07-27 08:31:56 +00003026 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003027 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false, meter)
mpagenko7d14de12021-07-27 08:31:56 +00003028 dh.lockVlanConfig.Unlock()
3029 return err
mpagenko01e726e2020-10-23 09:45:29 +00003030}
3031
3032//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00003033func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00003034 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3035 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3036 //no extra check is done on the rule parameters
3037 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3038 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3039 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3040 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003041 // - 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 +00003042 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003043 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003044
3045 /* TT related temporary workaround - should not be needed anymore
3046 for _, field := range flow.GetOfbFields(apFlowItem) {
3047 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3048 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00003049 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003050 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3051 if loIPProto == 2 {
3052 // 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 +00003053 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00003054 log.Fields{"device-id": dh.deviceID})
3055 return nil
3056 }
3057 }
3058 } //for all OfbFields
3059 */
3060
mpagenko9a304ea2020-12-16 15:54:01 +00003061 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003062 dh.lockVlanConfig.RLock()
3063 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00003064 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003065 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00003066 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003067 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00003068 log.Fields{"device-id": dh.deviceID})
3069 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003070 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00003071 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00003072
mpagenko01e726e2020-10-23 09:45:29 +00003073 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00003074}
3075
Himani Chawla26e555c2020-08-31 12:30:20 +05303076// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003077// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003078// precondition: dh.lockVlanConfig is locked by the caller!
mpagenko551a4d42020-12-08 18:09:20 +00003079func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003080 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
mpagenkodff5dda2020-08-28 11:52:01 +00003081 chVlanFilterFsm := make(chan Message, 2048)
3082
dbainbri4d3a0dc2020-12-02 00:33:42 +00003083 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003084 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003085 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303086 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003087 }
3088
dbainbri4d3a0dc2020-12-02 00:33:42 +00003089 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00003090 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003091 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter)
mpagenkodff5dda2020-08-28 11:52:01 +00003092 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003093 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3094 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Himani Chawla26e555c2020-08-31 12:30:20 +05303095 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003096 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3097 if pVlanFilterStatemachine != nil {
3098 if pVlanFilterStatemachine.Is(vlanStDisabled) {
3099 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003100 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05303101 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003102 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303103 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003104 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05303105 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3106 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003107 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003108 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003109 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303110 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003111 }
3112 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003113 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003114 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303115 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003116 }
3117 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003118 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003119 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05303120 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003121 }
3122 return nil
3123}
3124
mpagenkofc4f56e2020-11-04 17:17:49 +00003125//VerifyVlanConfigRequest checks on existence of a given uniPort
3126// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003127func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003128 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
3129 var pCurrentUniPort *onuUniPort
3130 for _, uniPort := range dh.uniEntityMap {
3131 // only if this port is validated for operState transfer
3132 if uniPort.uniID == uint8(aUniID) {
3133 pCurrentUniPort = uniPort
3134 break //found - end search loop
3135 }
3136 }
3137 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003138 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00003139 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
3140 return
3141 }
mpagenko551a4d42020-12-08 18:09:20 +00003142 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003143}
3144
mpagenkodff5dda2020-08-28 11:52:01 +00003145//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00003146func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003147 //TODO!! verify and start pending flow configuration
3148 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3149 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003150
3151 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303152 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003153 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003154 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
3155 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3156 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003157 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
3158 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
3159 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
3160 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
3161 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3162 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3163 } else {
3164 /***** UniVlanConfigFsm continued */
3165 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
3166 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3167 "UniPort": apUniPort.portNo})
3168 }
3169 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
3170 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
3171 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3172 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3173 } else {
3174 /***** UniVlanConfigFsm continued */
3175 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3176 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3177 "UniPort": apUniPort.portNo})
3178 }
mpagenkodff5dda2020-08-28 11:52:01 +00003179 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003180 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3181 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003182 "UniPort": apUniPort.portNo})
3183 }
3184 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003185 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3186 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3187 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003188 }
3189 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003190 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003191 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003192 }
mpagenkof1fc3862021-02-16 10:09:52 +00003193 } else {
3194 dh.lockVlanConfig.RUnlock()
3195 }
mpagenkodff5dda2020-08-28 11:52:01 +00003196}
3197
3198//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3199// 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 +00003200func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3201 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003202 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3203 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003204 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303205 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003206 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003207}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003208
mpagenkof1fc3862021-02-16 10:09:52 +00003209//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3210func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3211 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3212 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3213 // obviously then parallel processing on the cancel must be avoided
3214 // deadline context to ensure completion of background routines waited for
3215 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3216 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3217 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3218
3219 aPDevEntry.resetKvProcessingErrorIndication()
3220 var wg sync.WaitGroup
3221 wg.Add(1) // for the 1 go routine to finish
3222
3223 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3224 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3225
3226 return aPDevEntry.getKvProcessingErrorIndication()
3227}
3228
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003229//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3230//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003231func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3232 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003233
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003234 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003235 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003236 return nil
3237 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003238 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003239
dbainbri4d3a0dc2020-12-02 00:33:42 +00003240 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003241 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003242 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003243 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3244 }
3245 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3246
mpagenkof1fc3862021-02-16 10:09:52 +00003247 if aWriteToKvStore {
3248 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3249 }
3250 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003251}
3252
dbainbri4d3a0dc2020-12-02 00:33:42 +00003253func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003254 defer cancel() //ensure termination of context (may be pro forma)
3255 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003256 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003257 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003258}
3259
dbainbri4d3a0dc2020-12-02 00:33:42 +00003260func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003261
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003262 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003263 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003264 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003265 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3266 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003267 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003268 return err
3269 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003270 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003271 return nil
3272 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003273 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003274 return nil
3275}
3276
dbainbri4d3a0dc2020-12-02 00:33:42 +00003277func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3278 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003279 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003280 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003281 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3282 }
mpagenkof1fc3862021-02-16 10:09:52 +00003283 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003284}
3285
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003286func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
3287 var errStr string = ""
3288 for _, err := range errS {
3289 if err != nil {
3290 errStr = errStr + err.Error() + " "
3291 }
3292 }
3293 if errStr != "" {
3294 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
3295 }
3296 return nil
3297}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003298
3299// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003300// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003301func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3302 dh.lockDevice.RLock()
3303 defer dh.lockDevice.RUnlock()
3304 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3305 return uniPort.entityID, nil
3306 }
3307 return 0, errors.New("error-fetching-uni-port")
3308}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003309
3310// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003311func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3312 var errorsList []error
3313 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 -08003314
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003315 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3316 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3317 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3318
3319 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3320 // successfully.
3321 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3322 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3323 if len(errorsList) > 0 {
3324 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3325 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003326 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003327 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3328 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003329}
3330
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003331func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3332 var err error
3333 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003334 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003335
3336 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3337 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3338 errorsList = append(errorsList, err)
3339 }
3340 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003341 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003342
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003343 return errorsList
3344}
3345
3346func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3347 var err error
3348 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003349 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003350 // Check if group metric related config is updated
3351 for _, v := range pmConfigs.Groups {
3352 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3353 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3354 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3355
3356 if ok && m.frequency != v.GroupFreq {
3357 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3358 errorsList = append(errorsList, err)
3359 }
3360 }
3361 if ok && m.enabled != v.Enabled {
3362 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3363 errorsList = append(errorsList, err)
3364 }
3365 }
3366 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003367 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003368 return errorsList
3369}
3370
3371func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3372 var err error
3373 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003374 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003375 // Check if standalone metric related config is updated
3376 for _, v := range pmConfigs.Metrics {
3377 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003378 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003379 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3380
3381 if ok && m.frequency != v.SampleFreq {
3382 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3383 errorsList = append(errorsList, err)
3384 }
3385 }
3386 if ok && m.enabled != v.Enabled {
3387 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3388 errorsList = append(errorsList, err)
3389 }
3390 }
3391 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003392 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003393 return errorsList
3394}
3395
3396// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003397func (dh *deviceHandler) startCollector(ctx context.Context) {
3398 logger.Debugf(ctx, "startingCollector")
3399
3400 // Start routine to process OMCI GET Responses
3401 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303402 // Create Extended Frame PM ME
3403 go dh.pOnuMetricsMgr.createEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003404 // Initialize the next metric collection time.
3405 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3406 // reset like onu rebooted.
3407 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003408 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003409 for {
3410 select {
3411 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003412 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003413 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003414 // Stop the L2 PM FSM
3415 go func() {
3416 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3417 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3418 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3419 }
3420 } else {
3421 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3422 }
3423 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003424 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3425 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3426 }
3427 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3428 dh.pOnuMetricsMgr.stopTicks <- true
3429 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003430
Girish Gowdrae09a6202021-01-12 18:10:59 -08003431 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003432 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3433 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3434 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3435 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3436 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003437 // Update the next metric collection time.
3438 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003439 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003440 } else {
3441 if dh.pmConfigs.Grouped { // metrics are managed as a group
3442 // parse through the group and standalone metrics to see it is time to collect their metrics
3443 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003444
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003445 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3446 // 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 -08003447 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3448 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003449 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3450 }
3451 }
3452 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3453 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3454 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3455 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3456 }
3457 }
3458 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3459
3460 // parse through the group and update the next metric collection time
3461 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3462 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3463 // 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 -08003464 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3465 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003466 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3467 }
3468 }
3469 // parse through the standalone metrics and update the next metric collection time
3470 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3471 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3472 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3473 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3474 }
3475 }
3476 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3477 } /* else { // metrics are not managed as a group
3478 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3479 } */
3480 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003481 }
3482 }
3483}
kesavandfdf77632021-01-26 23:40:33 -05003484
3485func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3486
3487 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3488 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3489}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003490
Himani Chawla43f95ff2021-06-03 00:24:12 +05303491func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3492 if dh.pOnuMetricsMgr == nil {
3493 return &extension.SingleGetValueResponse{
3494 Response: &extension.GetValueResponse{
3495 Status: extension.GetValueResponse_ERROR,
3496 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3497 },
3498 }
3499 }
3500 resp := dh.pOnuMetricsMgr.collectEthernetFrameExtendedPMCounters(ctx)
3501 return resp
3502}
3503
mpagenkof1fc3862021-02-16 10:09:52 +00003504func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3505 if pFsm == nil {
3506 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003507 }
mpagenkof1fc3862021-02-16 10:09:52 +00003508 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003509}
3510
mpagenkof1fc3862021-02-16 10:09:52 +00003511func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3512 var pFsm *fsm.FSM
3513 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3514 switch omciFsm {
3515 case cUploadFsm:
3516 {
3517 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3518 }
3519 case cDownloadFsm:
3520 {
3521 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3522 }
3523 case cUniLockFsm:
3524 {
3525 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3526 }
3527 case cUniUnLockFsm:
3528 {
3529 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3530 }
3531 case cL2PmFsm:
3532 {
3533 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3534 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3535 } else {
3536 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003537 }
3538 }
mpagenko80622a52021-02-09 16:53:23 +00003539 case cOnuUpgradeFsm:
3540 {
3541 dh.lockUpgradeFsm.RLock()
3542 defer dh.lockUpgradeFsm.RUnlock()
3543 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3544 }
mpagenkof1fc3862021-02-16 10:09:52 +00003545 default:
3546 {
3547 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3548 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3549 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003550 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003551 }
mpagenkof1fc3862021-02-16 10:09:52 +00003552 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003553}
3554
mpagenkof1fc3862021-02-16 10:09:52 +00003555func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3556 for _, v := range dh.pOnuTP.pAniConfigFsm {
3557 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003558 return false
3559 }
3560 }
3561 return true
3562}
3563
mpagenkof1fc3862021-02-16 10:09:52 +00003564func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3565 dh.lockVlanConfig.RLock()
3566 defer dh.lockVlanConfig.RUnlock()
3567 for _, v := range dh.UniVlanConfigFsmMap {
3568 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3569 return false
3570 }
3571 }
3572 return true //FSM not active - so there is no activity on omci
3573}
3574
3575func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3576 dh.lockVlanConfig.RLock()
3577 defer dh.lockVlanConfig.RUnlock()
3578 for _, v := range dh.UniVlanConfigFsmMap {
3579 if v.pAdaptFsm.pFsm != nil {
3580 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3581 return true //there is at least one VLAN FSM with some active configuration
3582 }
3583 }
3584 }
3585 return false //there is no VLAN FSM with some active configuration
3586}
3587
3588func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3589 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3590 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3591 return false
3592 }
3593 }
3594 // a further check is done to identify, if at least some data traffic related configuration exists
3595 // 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])
3596 return dh.checkUserServiceExists(ctx)
3597}
3598
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003599func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3600 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3601 if err := dh.resetFsms(ctx, false); err != nil {
3602 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3603 // TODO: fatal error reset ONU, delete deviceHandler!
3604 return
3605 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003606 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003607 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003608}
3609
3610func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3611 dh.mutexCollectorFlag.Lock()
3612 dh.collectorIsRunning = flagValue
3613 dh.mutexCollectorFlag.Unlock()
3614}
3615
3616func (dh *deviceHandler) getCollectorIsRunning() bool {
3617 dh.mutexCollectorFlag.RLock()
3618 flagValue := dh.collectorIsRunning
3619 dh.mutexCollectorFlag.RUnlock()
3620 return flagValue
3621}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303622
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303623func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3624 dh.mutextAlarmManagerFlag.Lock()
3625 dh.alarmManagerIsRunning = flagValue
3626 dh.mutextAlarmManagerFlag.Unlock()
3627}
3628
Himani Chawla1472c682021-03-17 17:11:14 +05303629func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303630 dh.mutextAlarmManagerFlag.RLock()
3631 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303632 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303633 dh.mutextAlarmManagerFlag.RUnlock()
3634 return flagValue
3635}
3636
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303637func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3638 logger.Debugf(ctx, "startingAlarmManager")
3639
3640 // Start routine to process OMCI GET Responses
3641 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303642 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303643 if stop := <-dh.stopAlarmManager; stop {
3644 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303645 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303646 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303647 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3648 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3649 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303650 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303651 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303652 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3653 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303654 }
3655}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003656
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003657func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003658 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003659
Maninder7961d722021-06-16 22:10:28 +05303660 connectStatus := voltha.ConnectStatus_UNREACHABLE
3661 operState := voltha.OperStatus_UNKNOWN
3662
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003663 if !dh.isReconciling() {
3664 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003665 logger.Debugw(ctx, "wait for channel signal or timeout",
3666 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003667 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003668 case success := <-dh.chReconcilingFinished:
3669 if success {
Maninderb5187552021-03-23 22:23:42 +05303670 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3671 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3672 log.Fields{"device-id": dh.deviceID})
3673 } else {
Maninderb5187552021-03-23 22:23:42 +05303674 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3675 connectStatus = voltha.ConnectStatus_REACHABLE
3676 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3677 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3678 operState = voltha.OperStatus_ACTIVE
3679 } else {
3680 operState = voltha.OperStatus_ACTIVATING
3681 }
3682 }
3683 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3684 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3685 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3686 operState = voltha.OperStatus_DISCOVERED
3687 }
3688
3689 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303690 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003691 logger.Debugw(ctx, "reconciling has been finished in time",
3692 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303693 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, operState); err != nil {
3694 logger.Errorw(ctx, "unable to update device state to core",
3695 log.Fields{"device-id": dh.deviceID, "Err": err})
3696 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003697 } else {
Maninderb5187552021-03-23 22:23:42 +05303698 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003699 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303700
3701 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3702 logger.Errorw(ctx, "No valid OnuDevice",
3703 log.Fields{"device-id": dh.deviceID})
3704 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3705 connectStatus = voltha.ConnectStatus_REACHABLE
3706 }
3707
3708 dh.deviceReconcileFailedUpdate(ctx, drReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003709 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003710 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003711 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3712 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303713
3714 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3715 logger.Errorw(ctx, "No valid OnuDevice",
3716 log.Fields{"device-id": dh.deviceID})
3717 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3718 connectStatus = voltha.ConnectStatus_REACHABLE
3719 }
3720
3721 dh.deviceReconcileFailedUpdate(ctx, drReconcileMaxTimeout, connectStatus)
3722
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003723 }
3724 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003725 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003726 dh.mutexReconcilingFlag.Unlock()
3727 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003728 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003729 dh.mutexReconcilingFlag.Lock()
3730 if skipOnuConfig {
3731 dh.reconciling = cSkipOnuConfigReconciling
3732 } else {
3733 dh.reconciling = cOnuConfigReconciling
3734 }
3735 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003736}
3737
Girish Gowdra50e56422021-06-01 16:46:04 -07003738func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool) {
3739 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID, "success": success})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003740 if dh.isReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07003741 dh.chReconcilingFinished <- success
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003742 } else {
3743 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3744 }
3745}
3746
3747func (dh *deviceHandler) isReconciling() bool {
3748 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003749 defer dh.mutexReconcilingFlag.RUnlock()
3750 return dh.reconciling != cNoReconciling
3751}
3752
3753func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3754 dh.mutexReconcilingFlag.RLock()
3755 defer dh.mutexReconcilingFlag.RUnlock()
3756 return dh.reconciling == cSkipOnuConfigReconciling
3757}
3758
3759func (dh *deviceHandler) setDeviceReason(value uint8) {
3760 dh.mutexDeviceReason.Lock()
3761 dh.deviceReason = value
3762 dh.mutexDeviceReason.Unlock()
3763}
3764
3765func (dh *deviceHandler) getDeviceReason() uint8 {
3766 dh.mutexDeviceReason.RLock()
3767 value := dh.deviceReason
3768 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003769 return value
3770}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003771
3772func (dh *deviceHandler) getDeviceReasonString() string {
3773 return deviceReasonMap[dh.getDeviceReason()]
3774}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003775
3776func (dh *deviceHandler) setReconcilingFlows(value bool) {
3777 dh.mutexReconcilingFlowsFlag.Lock()
3778 dh.reconcilingFlows = value
3779 dh.mutexReconcilingFlowsFlag.Unlock()
3780}
3781
3782func (dh *deviceHandler) isReconcilingFlows() bool {
3783 dh.mutexReconcilingFlowsFlag.RLock()
3784 value := dh.reconcilingFlows
3785 dh.mutexReconcilingFlowsFlag.RUnlock()
3786 return value
3787}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003788
3789func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3790 dh.mutexReadyForOmciConfig.Lock()
3791 dh.readyForOmciConfig = flagValue
3792 dh.mutexReadyForOmciConfig.Unlock()
3793}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003794func (dh *deviceHandler) isReadyForOmciConfig() bool {
3795 dh.mutexReadyForOmciConfig.RLock()
3796 flagValue := dh.readyForOmciConfig
3797 dh.mutexReadyForOmciConfig.RUnlock()
3798 return flagValue
3799}
Maninder7961d722021-06-16 22:10:28 +05303800
3801func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
3802 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
3803 logger.Errorw(ctx, "unable to update device reason to core",
3804 log.Fields{"device-id": dh.deviceID, "Err": err})
3805 }
3806
3807 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
3808 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, voltha.OperStatus_RECONCILING_FAILED); err != nil {
3809 logger.Errorw(ctx, "unable to update device state to core",
3810 log.Fields{"device-id": dh.deviceID, "Err": err})
3811 }
3812}