blob: 4fb0a66d54f513bfaefc869c8650d647e7a15eaa [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
mpagenko2f487262021-08-23 15:59:06 +0000224 lockVlanAdd sync.RWMutex
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000225 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
226 lockUpgradeFsm sync.RWMutex
227 pOnuUpradeFsm *OnuUpgradeFsm
228 reconciling uint8
229 mutexReconcilingFlag sync.RWMutex
230 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000231 reconcilingFlows bool
232 mutexReconcilingFlowsFlag sync.RWMutex
233 chReconcilingFlowsFinished chan bool //channel to indicate that reconciling of flows has been finished
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000234 mutexReadyForOmciConfig sync.RWMutex
235 readyForOmciConfig bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000236 deletionInProgress bool
237 mutexDeletionInProgressFlag sync.RWMutex
mpagenkoaa3afe92021-05-21 16:20:58 +0000238 upgradeSuccess bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000239}
240
Himani Chawla6d2ae152020-09-02 13:11:20 +0530241//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530242func 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 +0530243 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000244 dh.coreProxy = cp
245 dh.AdapterProxy = ap
246 dh.EventProxy = ep
247 cloned := (proto.Clone(device)).(*voltha.Device)
248 dh.deviceID = cloned.Id
249 dh.DeviceType = cloned.Type
250 dh.adminState = "up"
251 dh.device = cloned
252 dh.pOpenOnuAc = adapter
253 dh.exitChannel = make(chan int, 1)
254 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000255 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000256 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000257 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530258 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530259 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000260 dh.stopHeartbeatCheck = make(chan bool, 2)
261 //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 +0000262 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530263 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000264 dh.lockVlanConfig = sync.RWMutex{}
mpagenko2f487262021-08-23 15:59:06 +0000265 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000266 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000267 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000268 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000269 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000270 dh.reconcilingFlows = false
271 dh.chReconcilingFlowsFinished = make(chan bool)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000272 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000273 dh.deletionInProgress = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000274
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800275 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
276 dh.pmConfigs = cloned.PmConfigs
277 } /* else {
278 // will be populated when onu_metrics_mananger is initialized.
279 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800280
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000281 // Device related state machine
282 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000283 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000284 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000285 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
286 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
287 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
288 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
289 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000290 },
291 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000292 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
293 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
294 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
295 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
296 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
297 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
298 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
299 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000300 },
301 )
mpagenkoaf801632020-07-03 10:00:42 +0000302
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000303 return &dh
304}
305
Himani Chawla6d2ae152020-09-02 13:11:20 +0530306// start save the device to the data model
307func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000308 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000309 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000310 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000311}
312
Himani Chawla4d908332020-08-31 12:30:20 +0530313/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000314// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530315func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000316 logger.Debug("stopping-device-handler")
317 dh.exitChannel <- 1
318}
Himani Chawla4d908332020-08-31 12:30:20 +0530319*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000320
321// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530322// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000323
Girish Gowdrae0140f02021-02-02 16:55:09 -0800324//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530325func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000326 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000327
dbainbri4d3a0dc2020-12-02 00:33:42 +0000328 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000329 if dh.pDeviceStateFsm.Is(devStNull) {
330 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000331 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000332 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000333 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800334 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
335 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800336 // Now, set the initial PM configuration for that device
337 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
338 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
339 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800340 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000341 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000342 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000343 }
344
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000345}
346
mpagenko057889c2021-01-21 16:51:58 +0000347func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530348 msgBody := msg.GetBody()
349 omciMsg := &ic.InterAdapterOmciMessage{}
350 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000351 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530352 "device-id": dh.deviceID, "error": err})
353 return err
354 }
355
mpagenko80622a52021-02-09 16:53:23 +0000356 /* 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 +0530357 //assuming omci message content is hex coded!
358 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000359 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530360 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000361 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000362 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530363 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000364 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000365 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000366 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000367 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 +0530368 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000369 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000370 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530371}
372
Himani Chawla6d2ae152020-09-02 13:11:20 +0530373func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000374 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530375 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000376
dbainbri4d3a0dc2020-12-02 00:33:42 +0000377 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000378
dbainbri4d3a0dc2020-12-02 00:33:42 +0000379 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000380 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000381 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000382 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
383 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530384 if dh.pOnuTP == nil {
385 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000386 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530387 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000388 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530389 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000390 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000391 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000392 "device-state": dh.getDeviceReasonString()})
393 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530394 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000395 //previous state test here was just this one, now extended for more states to reject the SetRequest:
396 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
397 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530398
399 msgBody := msg.GetBody()
400 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
401 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000402 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530403 "device-id": dh.deviceID, "error": err})
404 return err
405 }
406
407 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000408 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
409 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530410 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000411 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000412
413 if techProfMsg.UniId > 255 {
414 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
415 techProfMsg.UniId, dh.deviceID))
416 }
417 uniID := uint8(techProfMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700418 tpID, err := GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800419 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700420 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800421 return err
422 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700423 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000424
Girish Gowdra50e56422021-06-01 16:46:04 -0700425 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530426
Girish Gowdra50e56422021-06-01 16:46:04 -0700427 switch tpInst := techProfMsg.TechTpInstance.(type) {
428 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance:
429 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
430 // if there has been some change for some uni TechProfilePath
431 //in order to allow concurrent calls to other dh instances we do not wait for execution here
432 //but doing so we can not indicate problems to the caller (who does what with that then?)
433 //by now we just assume straightforward successful execution
434 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
435 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530436
Girish Gowdra50e56422021-06-01 16:46:04 -0700437 // deadline context to ensure completion of background routines waited for
438 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
439 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
440 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000441
Girish Gowdra50e56422021-06-01 16:46:04 -0700442 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
443
444 var wg sync.WaitGroup
445 wg.Add(1) // for the 1 go routine to finish
446 // attention: deadline completion check and wg.Done is to be done in both routines
447 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
448 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
449 if tpErr := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
450 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.deviceID, "err": tpErr, "tp-path": techProfMsg.TpInstancePath})
451 return tpErr
452 }
453 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
454 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
455 pDevEntry.resetKvProcessingErrorIndication()
456 wg.Add(1) // for the 1 go routine to finish
457 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
458 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
459 if kvErr := pDevEntry.getKvProcessingErrorIndication(); kvErr != nil {
460 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.deviceID, "err": kvErr, "tp-path": techProfMsg.TpInstancePath})
461 return kvErr
462 }
463 return nil
464 default:
465 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"tp-path": techProfMsg.TpInstancePath})
466 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700467 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530468 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000469 // no change, nothing really to do - return success
Girish Gowdra50e56422021-06-01 16:46:04 -0700470 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 +0530471 return nil
472}
473
Himani Chawla6d2ae152020-09-02 13:11:20 +0530474func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000475 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530476 msg *ic.InterAdapterMessage) error {
477
478 if dh.pOnuTP == nil {
479 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000480 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530481 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000482 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530483 }
484
485 msgBody := msg.GetBody()
486 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
487 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000488 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530489 "device-id": dh.deviceID, "error": err})
490 return err
491 }
492
493 //compare TECH_PROFILE_DOWNLOAD_REQUEST
494 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000495 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530496
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000497 if delGemPortMsg.UniId > 255 {
498 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
499 delGemPortMsg.UniId, dh.deviceID))
500 }
501 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700502 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800503 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700504 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 -0800505 return err
506 }
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700507 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000508 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000509
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700510 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
511 cResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000512
Himani Chawla26e555c2020-08-31 12:30:20 +0530513}
514
Himani Chawla6d2ae152020-09-02 13:11:20 +0530515func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000516 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530517 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000518
dbainbri4d3a0dc2020-12-02 00:33:42 +0000519 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000520 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000521 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000522 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
523 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530524 if dh.pOnuTP == nil {
525 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000526 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530527 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000528 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530529 }
530
531 msgBody := msg.GetBody()
532 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
533 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000534 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530535 "device-id": dh.deviceID, "error": err})
536 return err
537 }
538
539 //compare TECH_PROFILE_DOWNLOAD_REQUEST
540 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000541 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000542
543 if delTcontMsg.UniId > 255 {
544 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
545 delTcontMsg.UniId, dh.deviceID))
546 }
547 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700548 tpPath := delTcontMsg.TpInstancePath
Girish Gowdra041dcb32020-11-16 16:54:30 -0800549 tpID, err := GetTpIDFromTpPath(tpPath)
550 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000551 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800552 return err
553 }
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700554 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID, "tcont": delTcontMsg.AllocId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000555
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700556 pDevEntry.freeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530557
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700558 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
559 cResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000560
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700561}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000562
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700563func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
564 uniID uint8, tpID uint8, pathString string, resource resourceEntry, entryID uint32) error {
565 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
566 if pDevEntry == nil {
567 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
568 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530569 }
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700570 var resourceName string
571 if cResourceGemPort == resource {
572 resourceName = "Gem"
573 } else {
574 resourceName = "Tcont"
575 }
576
577 // deadline context to ensure completion of background routines waited for
578 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
579 dctx, cancel := context.WithDeadline(context.Background(), deadline)
580
581 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
582
583 var wg sync.WaitGroup
584 wg.Add(1) // for the 1 go routine to finish
585 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
586 resource, entryID, &wg)
587 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
588 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); err != nil {
589 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
590 return err
591 }
592
593 if dh.pOnuTP.isTechProfileConfigCleared(ctx, uniID, tpID) {
594 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID})
595 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
596 pDevEntry.resetKvProcessingErrorIndication()
597 var wg2 sync.WaitGroup
598 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
599 wg2.Add(1)
600 // Removal of the gem id mapping represents the removal of the tech profile
601 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID})
602 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
603 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
604 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
605 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
606 return err
607 }
608 }
609 }
610 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.deviceID,
611 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530612 return nil
613}
614
Himani Chawla6d2ae152020-09-02 13:11:20 +0530615//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000616// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
617// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000618func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000619 msgID := msg.Header.Id
620 msgType := msg.Header.Type
621 fromTopic := msg.Header.FromTopic
622 toTopic := msg.Header.ToTopic
623 toDeviceID := msg.Header.ToDeviceId
624 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000625 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000626 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
627
628 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000629 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000630 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
631 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000632 {
mpagenko057889c2021-01-21 16:51:58 +0000633 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000634 }
mpagenkoaf801632020-07-03 10:00:42 +0000635 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
636 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000637 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000638 }
639 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
640 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000641 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000642
mpagenkoaf801632020-07-03 10:00:42 +0000643 }
644 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
645 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000646 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000647 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000648 default:
649 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000650 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000651 "msgType": msg.Header.Type, "device-id": dh.deviceID})
652 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000653 }
654 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000655}
656
mpagenkodff5dda2020-08-28 11:52:01 +0000657//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000658func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
659 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000660 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
ozgecanetsia82b91a62021-05-21 18:54:49 +0300661 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID, "metadata": apFlowMetaData})
mpagenko01e726e2020-10-23 09:45:29 +0000662 var retError error = nil
663 //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 +0000664 if apOfFlowChanges.ToRemove != nil {
665 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000666 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000667 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000668 "device-id": dh.deviceID})
669 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000670 continue
671 }
672 flowInPort := flow.GetInPort(flowItem)
673 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000674 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 +0000675 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
676 continue
677 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000678 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000679 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000680 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000681 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000682 continue
683 } else {
684 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530685 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000686 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
687 loUniPort = uniPort
688 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000689 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000690 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
691 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
692 flowInPort, dh.deviceID)
693 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000694 }
695 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000696 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000697 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000698 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000699 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000700 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000701 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000702 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000703 log.Fields{"device-id": dh.deviceID, "error": err})
704 retError = err
705 continue
706 //return err
707 } else { // if last setting succeeds, overwrite possibly previously set error
708 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000709 }
710 }
711 }
712 }
mpagenko01e726e2020-10-23 09:45:29 +0000713 if apOfFlowChanges.ToAdd != nil {
714 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
715 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000716 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000717 "device-id": dh.deviceID})
718 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
719 continue
720 }
721 flowInPort := flow.GetInPort(flowItem)
722 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000723 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 +0000724 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
725 continue
726 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
727 } else if flowInPort == dh.ponPortNumber {
728 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000729 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000730 "device-id": dh.deviceID, "inPort": flowInPort})
731 continue
732 } else {
733 // this is the relevant upstream flow
734 var loUniPort *onuUniPort
735 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
736 loUniPort = uniPort
737 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000738 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000739 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
740 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
741 flowInPort, dh.deviceID)
742 continue
743 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
744 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000745 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
746 // if not, we just throw some error here to have an indication about that, if we really need to support that
747 // then we would need to create some means to activate the internal stored flows
748 // after the device gets active automatically (and still with its dependency to the TechProfile)
749 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
750 // also abort for the other still possible flows here
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000751 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000752 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000753 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000754 return fmt.Errorf("improper device state on device %s", dh.deviceID)
755 }
756
mpagenko01e726e2020-10-23 09:45:29 +0000757 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000758 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000759 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
760 "uniPortName": loUniPort.name})
ozgecanetsia82b91a62021-05-21 18:54:49 +0300761 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort, apFlowMetaData)
mpagenko01e726e2020-10-23 09:45:29 +0000762 //try next flow after processing error
763 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000764 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000765 log.Fields{"device-id": dh.deviceID, "error": err})
766 retError = err
767 continue
768 //return err
769 } else { // if last setting succeeds, overwrite possibly previously set error
770 retError = nil
771 }
772 }
773 }
774 }
775 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000776}
777
Himani Chawla6d2ae152020-09-02 13:11:20 +0530778//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000779//following are the expected device states after this activity:
780//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
781// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000782func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
783 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000784
mpagenko900ee4b2020-10-12 11:56:34 +0000785 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000786 //note that disableDevice sequences in some 'ONU active' state may yield also
787 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000788 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000789 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000790 //disable-device shall be just a UNi/ONU-G related admin state setting
791 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000792
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000793 if dh.isReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000794 // disable UNI ports/ONU
795 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
796 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000797 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000798 } else { //LockStateFSM already init
799 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000800 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000801 }
802 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000803 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000804 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000805 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000806 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
807 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000808 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000809 }
mpagenko01e726e2020-10-23 09:45:29 +0000810 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000811
812 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000813 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000814 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300815 }
816}
817
Himani Chawla6d2ae152020-09-02 13:11:20 +0530818//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000819func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
820 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000821
mpagenkoaa3afe92021-05-21 16:20:58 +0000822 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000823 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
824 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
825 // for real ONU's that should have nearly no influence
826 // Note that for real ONU's there is anyway a problematic situation with following sequence:
827 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
828 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
829 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000830 dh.setReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000831
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000832 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000833 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000834 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000835 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000836 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000837 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000838 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000839 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300840}
841
dbainbri4d3a0dc2020-12-02 00:33:42 +0000842func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
843 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000844
dbainbri4d3a0dc2020-12-02 00:33:42 +0000845 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000846 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000847 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000848 return
849 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000850 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000851 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000852 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000853 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000854 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000855 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700856 dh.stopReconciling(ctx, false)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000857 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000858 }
Himani Chawla4d908332020-08-31 12:30:20 +0530859 var onuIndication oop.OnuIndication
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000860 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000861 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
862 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
863 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
864 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000865 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000866 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000867}
868
dbainbri4d3a0dc2020-12-02 00:33:42 +0000869func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
870 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000871
dbainbri4d3a0dc2020-12-02 00:33:42 +0000872 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000873 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000874 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000875 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700876 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000877 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000878 return
879 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000880 dh.pOnuTP.lockTpProcMutex()
881 defer dh.pOnuTP.unlockTpProcMutex()
882
mpagenko5dc85a02021-08-02 12:35:01 +0000883 pDevEntry.mutexPersOnuConfig.RLock()
884 persMutexLock := true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000885 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko5dc85a02021-08-02 12:35:01 +0000886 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000887 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000888 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000889 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700890 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000891 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000892 return
893 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000894 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700895 techProfsFound := false
896 techProfInstLoadFailed := false
897outerLoop:
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000898 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000899 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
900 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000901 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000902 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000903 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000904 }
mpagenko5dc85a02021-08-02 12:35:01 +0000905 //release mutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
906 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
907 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
908 pDevEntry.mutexPersOnuConfig.RUnlock()
909 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700910 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800911 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700912 // Request the TpInstance again from the openolt adapter in case of reconcile
913 iaTechTpInst, err := dh.AdapterProxy.TechProfileInstanceRequest(ctx, uniData.PersTpPathMap[tpID],
914 dh.device.ParentPortNo, dh.device.ProxyAddress.OnuId, uint32(uniData.PersUniID),
915 dh.pOpenOnuAc.config.Topic, dh.ProxyAddressType,
916 dh.parentID, dh.ProxyAddressID)
917 if err != nil || iaTechTpInst == nil {
918 logger.Errorw(ctx, "error fetching tp instance",
919 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID, "err": err})
920 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
921 break outerLoop
922 }
923 var tpInst tech_profile.TechProfileInstance
924 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
925 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
926 tpInst = *techTpInst.TpInstance
mpagenko5dc85a02021-08-02 12:35:01 +0000927 logger.Debugw(ctx, "received-tp-instance-successfully-after-reconcile", log.Fields{
928 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700929 default: // do not support epon or other tech
mpagenko5dc85a02021-08-02 12:35:01 +0000930 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
931 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700932 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
933 break outerLoop
934 }
935
Girish Gowdra041dcb32020-11-16 16:54:30 -0800936 // deadline context to ensure completion of background routines waited for
937 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
938 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000939 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000940
Girish Gowdra041dcb32020-11-16 16:54:30 -0800941 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
942 var wg sync.WaitGroup
943 wg.Add(1) // for the 1 go routine to finish
Girish Gowdra50e56422021-06-01 16:46:04 -0700944 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000945 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800946 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000947 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700948 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
949 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800950 }
mpagenko5dc85a02021-08-02 12:35:01 +0000951 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000952 if len(uniData.PersFlowParams) != 0 {
953 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000954 }
mpagenko5dc85a02021-08-02 12:35:01 +0000955 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
956 persMutexLock = true
957 } // for all UNI entries from sOnuPersistentData
958 if persMutexLock { // if loop was left with mutexPersOnuConfig still set
959 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000960 }
mpagenko5dc85a02021-08-02 12:35:01 +0000961
962 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
963 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
964}
965
966func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
967 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
968 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000969 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
970 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000971 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700972 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000973 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000974 return
975 }
mpagenko5dc85a02021-08-02 12:35:01 +0000976 if abTechProfInstLoadFailed {
Girish Gowdra50e56422021-06-01 16:46:04 -0700977 dh.setDeviceReason(drTechProfileConfigDownloadFailed)
978 dh.stopReconciling(ctx, false)
979 return
980 } else if dh.isSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000981 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
982 }
mpagenko5dc85a02021-08-02 12:35:01 +0000983 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000984 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
985 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000986 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700987 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000988 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000989 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000990}
991
dbainbri4d3a0dc2020-12-02 00:33:42 +0000992func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
993 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000994
dbainbri4d3a0dc2020-12-02 00:33:42 +0000995 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000996 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000997 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000998 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700999 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001000 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001001 return
1002 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001003
mpagenko5dc85a02021-08-02 12:35:01 +00001004 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001005 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko5dc85a02021-08-02 12:35:01 +00001006 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001007 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001008 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001009 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001010 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001011 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001012 return
1013 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001014 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001015 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001016 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1017 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001018 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001019 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001020 continue
1021 }
1022 if len(uniData.PersTpPathMap) == 0 {
1023 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
1024 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001025 // It doesn't make sense to configure any flows if no TPs are available
1026 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001027 }
mpagenko5dc85a02021-08-02 12:35:01 +00001028 //release mutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1029 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
1030 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1031 pDevEntry.mutexPersOnuConfig.RUnlock()
1032
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001033 var uniPort *onuUniPort
1034 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +00001035 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001036 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001037 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
1038 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001039 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001040 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001041 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001042 return
1043 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001044 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001045 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001046 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001047 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001048 for _, flowData := range uniData.PersFlowParams {
mpagenko5dc85a02021-08-02 12:35:01 +00001049 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1050 "device-id": dh.deviceID, "uni-id": uniData.PersUniID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001051 // If this is the last flow for the device we need to announce it the waiting
1052 // chReconcilingFlowsFinished channel
1053 if flowsProcessed == len(uniData.PersFlowParams)-1 {
1054 lastFlowToReconcile = true
1055 }
mpagenko01e726e2020-10-23 09:45:29 +00001056 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenko37047052021-07-27 10:01:29 +00001057 dh.lockVlanConfig.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001058 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001059 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +00001060 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +03001061 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001062 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001063 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001064 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001065 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00001066 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +03001067 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001068 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001069 }
1070 }
mpagenko37047052021-07-27 10:01:29 +00001071 dh.lockVlanConfig.Unlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001072 flowsProcessed++
mpagenko5dc85a02021-08-02 12:35:01 +00001073 } //for all flows of this UNI
1074 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
1075 "device-id": dh.deviceID, "uni-id": uniData.PersUniID, "flowsProcessed": flowsProcessed,
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001076 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
1077 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001078 // this can't be used as global finished reconciling flag because
1079 // assumes is getting called before the state machines for the last flow is completed,
1080 // while this is not guaranteed.
1081 //dh.setReconcilingFlows(false)
mpagenko5dc85a02021-08-02 12:35:01 +00001082 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
1083 } // for all UNI entries from sOnuPersistentData
1084 pDevEntry.mutexPersOnuConfig.RUnlock()
1085
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001086 if !flowsFound {
1087 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
1088 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001089 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001090 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001091 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001092 return
1093 }
1094 if dh.isSkipOnuConfigReconciling() {
1095 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001096 }
1097}
1098
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001099func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
1100 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001101 dh.stopReconciling(ctx, true)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001102}
1103
dbainbri4d3a0dc2020-12-02 00:33:42 +00001104func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
1105 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001106
dbainbri4d3a0dc2020-12-02 00:33:42 +00001107 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001108 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001109 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +00001110 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001111 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001112 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001113
1114 // deadline context to ensure completion of background routines waited for
1115 //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 +05301116 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001117 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001118
1119 pDevEntry.resetKvProcessingErrorIndication()
1120
1121 var wg sync.WaitGroup
1122 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001123 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1124 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001125
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001126 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001127 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001128}
1129
mpagenko15ff4a52021-03-02 10:09:20 +00001130//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1131// before this change here return like this was used:
1132// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1133//was and is called in background - error return does not make sense
1134func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1135 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1136 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001137 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001138 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001139 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001140 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301141 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001142 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001143 return
Himani Chawla4d908332020-08-31 12:30:20 +05301144 }
mpagenko01e726e2020-10-23 09:45:29 +00001145
1146 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001147 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001148
dbainbri4d3a0dc2020-12-02 00:33:42 +00001149 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001150 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001151 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001152 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001153 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001154 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001155 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001156 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001157 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001158 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001159 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001160 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001161 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1162 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1163 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1164 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001165}
1166
mpagenkoc8bba412021-01-15 15:38:44 +00001167//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +00001168func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1169 apDownloadManager *adapterDownloadManager) error {
1170 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001171 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001172
1173 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001174 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1175 if pDevEntry == nil {
1176 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1177 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1178 }
1179
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001180 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001181 var inactiveImageID uint16
1182 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1183 dh.lockUpgradeFsm.Lock()
1184 defer dh.lockUpgradeFsm.Unlock()
1185 if dh.pOnuUpradeFsm == nil {
1186 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1187 if err == nil {
1188 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1189 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1190 "device-id": dh.deviceID, "error": err})
1191 }
1192 } else {
1193 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001194 "device-id": dh.deviceID, "error": err})
1195 }
mpagenko15ff4a52021-03-02 10:09:20 +00001196 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1197 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1198 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1199 if pUpgradeStatemachine != nil {
1200 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1201 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1202 "device-id": dh.deviceID, "error": err})
1203 }
1204 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1205 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1206 // for now a second start of download should work again
1207 } else { //should never occur
1208 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1209 "device-id": dh.deviceID})
1210 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001211 }
mpagenko80622a52021-02-09 16:53:23 +00001212 }
mpagenko15ff4a52021-03-02 10:09:20 +00001213 } else {
1214 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1215 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001216 }
1217 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001218 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1219 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001220 }
1221 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001222}
1223
mpagenkoc26d4c02021-05-06 14:27:57 +00001224//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1225// after the OnuImage has been downloaded to the adapter, called in background
1226func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
1227 apDownloadManager *fileDownloadManager, aImageIdentifier string) {
1228
1229 var err error
1230 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1231 if pDevEntry == nil {
1232 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1233 return
1234 }
1235
1236 var inactiveImageID uint16
1237 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1238 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
1239 "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
1240 dh.lockUpgradeFsm.Lock()
1241 defer dh.lockUpgradeFsm.Unlock()
1242 if dh.pOnuUpradeFsm == nil {
1243 //OmciOnuSwUpgradeDone could be used to create some Kafka event with information on upgrade completion,
1244 // but none yet defined
1245 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1246 if err == nil {
1247 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
Holger Hildebrandtac010732021-06-02 13:35:39 +00001248 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00001249 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1250 "device-id": dh.deviceID, "error": err})
1251 return
1252 }
1253 } else {
1254 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1255 "device-id": dh.deviceID, "error": err})
1256 }
1257 return
1258 }
1259 //OnuSw upgrade already running - restart (with possible abort of running)
1260 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1261 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1262 if pUpgradeStatemachine != nil {
1263 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1264 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1265 "device-id": dh.deviceID, "error": err})
1266 return
1267 }
1268 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1269 // for now a second start of download should work again - must still be initiated by user
1270 } else { //should never occur
1271 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1272 "device-id": dh.deviceID})
1273 }
1274 return
1275 }
1276 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1277 "device-id": dh.deviceID, "error": err})
1278}
1279
1280//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001281func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1282 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001283 var err error
1284 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1285 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1286 // 2.) activation of the inactive image
1287
1288 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1289 if pDevEntry == nil {
1290 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001291 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001292 }
1293 dh.lockUpgradeFsm.RLock()
1294 if dh.pOnuUpradeFsm != nil {
1295 dh.lockUpgradeFsm.RUnlock()
1296 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1297 dh.deviceID, dh.deviceID)
1298 if getErr != nil || onuVolthaDevice == nil {
1299 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 +00001300 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001301 }
1302 // use the OnuVendor identification from this device for the internal unique name
1303 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1304 // 1.) check a started upgrade process and rely the activation request to it
1305 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001306 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001307 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1308 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001309 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001310 }
mpagenko183647c2021-06-08 15:25:04 +00001311 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1312 "device-id": dh.deviceID, "image-id": imageIdentifier})
1313 var pImageStates *voltha.ImageState
1314 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1315 pImageStates = &voltha.ImageState{}
1316 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1317 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1318 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1319 }
1320 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001321 } //else
1322 dh.lockUpgradeFsm.RUnlock()
1323
1324 // 2.) check if requested image-version equals the inactive one and start its activation
1325 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1326 var inactiveImageID uint16
1327 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1328 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1329 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
mpagenko183647c2021-06-08 15:25:04 +00001330 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001331 }
1332 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1333 if err == nil {
1334 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1335 inactiveImageID, aCommitRequest); err != nil {
1336 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1337 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001338 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001339 }
1340 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1341 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001342 var pImageStates *voltha.ImageState
1343 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1344 pImageStates := &voltha.ImageState{}
1345 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1346 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1347 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1348 }
1349 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001350 } //else
1351 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1352 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001353 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001354}
1355
1356//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001357func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1358 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001359 var err error
1360 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1361 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1362 // 2.) commitment of the active image
1363
1364 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1365 if pDevEntry == nil {
1366 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001367 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001368 }
1369 dh.lockUpgradeFsm.RLock()
1370 if dh.pOnuUpradeFsm != nil {
1371 dh.lockUpgradeFsm.RUnlock()
1372 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1373 dh.deviceID, dh.deviceID)
1374 if getErr != nil || onuVolthaDevice == nil {
1375 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 +00001376 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001377 }
1378 // use the OnuVendor identification from this device for the internal unique name
1379 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1380 // 1.) check a started upgrade process and rely the commitment request to it
1381 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001382 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001383 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1384 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001385 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001386 }
mpagenko183647c2021-06-08 15:25:04 +00001387 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1388 "device-id": dh.deviceID, "image-id": imageIdentifier})
1389 var pImageStates *voltha.ImageState
1390 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1391 pImageStates := &voltha.ImageState{}
1392 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1393 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1394 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1395 }
1396 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001397 } //else
1398 dh.lockUpgradeFsm.RUnlock()
1399
mpagenko183647c2021-06-08 15:25:04 +00001400 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001401 var activeImageID uint16
1402 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1403 logger.Errorw(ctx, "get active image failed", log.Fields{
1404 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
mpagenko183647c2021-06-08 15:25:04 +00001405 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001406 }
1407 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1408 if err == nil {
1409 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1410 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1411 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001412 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001413 }
1414 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1415 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001416 var pImageStates *voltha.ImageState
1417 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1418 pImageStates := &voltha.ImageState{}
1419 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1420 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1421 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1422 }
1423 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001424 } //else
1425 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1426 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001427 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001428}
1429
mpagenkoaa3afe92021-05-21 16:20:58 +00001430func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
1431 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1432 pDeviceImageState.DeviceId = dh.deviceID
mpagenko183647c2021-06-08 15:25:04 +00001433 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001434 dh.lockUpgradeFsm.RLock()
1435 if dh.pOnuUpradeFsm != nil {
1436 dh.lockUpgradeFsm.RUnlock()
mpagenko183647c2021-06-08 15:25:04 +00001437 if pImageStates, err := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion); err == nil {
mpagenkoaa3afe92021-05-21 16:20:58 +00001438 pDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
1439 pDeviceImageState.ImageState.Reason = pImageStates.Reason
1440 pDeviceImageState.ImageState.ImageState = pImageStates.ImageState
1441 } else {
1442 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1443 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1444 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1445 }
1446 } else {
1447 dh.lockUpgradeFsm.RUnlock()
1448 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1449 if dh.upgradeSuccess {
1450 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
1451 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMITTED
1452 } else {
1453 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1454 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1455 }
1456 }
1457}
1458
1459func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1460 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1461 pDeviceImageState.DeviceId = dh.deviceID
mpagenko7455fd42021-06-10 16:25:55 +00001462 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001463 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1464 dh.lockUpgradeFsm.RLock()
1465 if dh.pOnuUpradeFsm != nil {
1466 dh.lockUpgradeFsm.RUnlock()
1467 //option: it could be also checked if the upgrade FSM is running on the given imageIdentifier or version
1468 // by now just straightforward assume this to be true
1469 dh.pOnuUpradeFsm.CancelProcessing(ctx)
1470 //nolint:misspell
1471 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
1472 //nolint:misspell
1473 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1474 } else {
1475 dh.lockUpgradeFsm.RUnlock()
1476 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1477 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1478 }
1479}
1480
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001481func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1482
1483 var onuImageStatus *OnuImageStatus
1484
1485 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1486 if pDevEntry != nil {
1487 onuImageStatus = NewOnuImageStatus(pDevEntry)
1488 pDevEntry.mutexOnuImageStatus.Lock()
1489 pDevEntry.pOnuImageStatus = onuImageStatus
1490 pDevEntry.mutexOnuImageStatus.Unlock()
1491
1492 } else {
1493 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1494 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1495 }
1496 images, err := onuImageStatus.getOnuImageStatus(ctx)
1497 pDevEntry.mutexOnuImageStatus.Lock()
1498 pDevEntry.pOnuImageStatus = nil
1499 pDevEntry.mutexOnuImageStatus.Unlock()
1500 return images, err
1501}
1502
Himani Chawla6d2ae152020-09-02 13:11:20 +05301503// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001504// #####################################################################################
1505
1506// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301507// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001508
dbainbri4d3a0dc2020-12-02 00:33:42 +00001509func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1510 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 +00001511}
1512
1513// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001514func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001515
dbainbri4d3a0dc2020-12-02 00:33:42 +00001516 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001517 var err error
1518
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001519 // populate what we know. rest comes later after mib sync
1520 dh.device.Root = false
1521 dh.device.Vendor = "OpenONU"
1522 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001523 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001524 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001525
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001526 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001527
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001528 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001529 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1530 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301531 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001532 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001533 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001534 log.Fields{"device-id": dh.deviceID})
1535 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001536
Himani Chawla4d908332020-08-31 12:30:20 +05301537 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001538 dh.ponPortNumber = dh.device.ParentPortNo
1539
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001540 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1541 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1542 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001543 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001544 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301545 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001546
1547 /*
1548 self._pon = PonPort.create(self, self._pon_port_number)
1549 self._pon.add_peer(self.parent_id, self._pon_port_number)
1550 self.logger.debug('adding-pon-port-to-agent',
1551 type=self._pon.get_port().type,
1552 admin_state=self._pon.get_port().admin_state,
1553 oper_status=self._pon.get_port().oper_status,
1554 )
1555 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001556 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001557 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001558 var ponPortNo uint32 = 1
1559 if dh.ponPortNumber != 0 {
1560 ponPortNo = dh.ponPortNumber
1561 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001562
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001563 pPonPort := &voltha.Port{
1564 PortNo: ponPortNo,
1565 Label: fmt.Sprintf("pon-%d", ponPortNo),
1566 Type: voltha.Port_PON_ONU,
1567 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301568 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001569 PortNo: ponPortNo}}, // Peer port is parent's port number
1570 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001571 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1572 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001573 e.Cancel(err)
1574 return
1575 }
1576 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001577 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001578 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001579 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001580}
1581
1582// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001583func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001584
dbainbri4d3a0dc2020-12-02 00:33:42 +00001585 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001586 var err error
1587 /*
1588 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1589 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1590 return nil
1591 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001592 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1593 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001594 e.Cancel(err)
1595 return
1596 }
1597
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001598 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001599 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001600 // reconcilement will be continued after mib download is done
1601 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001602
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001603 /*
1604 ############################################################################
1605 # Setup Alarm handler
1606 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1607 device.serial_number)
1608 ############################################################################
1609 # Setup PM configuration for this device
1610 # Pass in ONU specific options
1611 kwargs = {
1612 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1613 'heartbeat': self.heartbeat,
1614 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1615 }
1616 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1617 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1618 self.logical_device_id, device.serial_number,
1619 grouped=True, freq_override=False, **kwargs)
1620 pm_config = self._pm_metrics.make_proto()
1621 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1622 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1623 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1624
1625 # Note, ONU ID and UNI intf set in add_uni_port method
1626 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1627 ani_ports=[self._pon])
1628
1629 # Code to Run OMCI Test Action
1630 kwargs_omci_test_action = {
1631 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1632 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1633 }
1634 serial_number = device.serial_number
1635 self._test_request = OmciTestRequest(self.core_proxy,
1636 self.omci_agent, self.device_id,
1637 AniG, serial_number,
1638 self.logical_device_id,
1639 exclusive=False,
1640 **kwargs_omci_test_action)
1641
1642 self.enabled = True
1643 else:
1644 self.logger.info('onu-already-activated')
1645 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001646
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001648}
1649
1650// doStateConnected get the device info and update to voltha core
1651// for comparison of the original method (not that easy to uncomment): compare here:
1652// voltha-openolt-adapter/adaptercore/device_handler.go
1653// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001655
dbainbri4d3a0dc2020-12-02 00:33:42 +00001656 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301657 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001658 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001659 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001660}
1661
1662// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001663func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001664
dbainbri4d3a0dc2020-12-02 00:33:42 +00001665 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301666 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001667 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001668 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001669
1670 /*
1671 // Synchronous call to update device state - this method is run in its own go routine
1672 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1673 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001674 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 +00001675 return err
1676 }
1677 return nil
1678 */
1679}
1680
1681// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001682func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001683
dbainbri4d3a0dc2020-12-02 00:33:42 +00001684 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001685 var err error
1686
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001687 device := dh.device
1688 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001689 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001690 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001691 e.Cancel(err)
1692 return
1693 }
1694
1695 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001696 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001697 /*
1698 // Update the all ports state on that device to disable
1699 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001700 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001701 return er
1702 }
1703
1704 //Update the device oper state and connection status
1705 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1706 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1707 dh.device = cloned
1708
1709 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001710 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001711 return er
1712 }
1713
1714 //get the child device for the parent device
1715 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1716 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001717 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001718 return err
1719 }
1720 for _, onuDevice := range onuDevices.Items {
1721
1722 // Update onu state as down in onu adapter
1723 onuInd := oop.OnuIndication{}
1724 onuInd.OperState = "down"
1725 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1726 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1727 if er != nil {
1728 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001729 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001730 //Do not return here and continue to process other ONUs
1731 }
1732 }
1733 // * Discovered ONUs entries need to be cleared , since after OLT
1734 // is up, it starts sending discovery indications again* /
1735 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001736 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001737 return nil
1738 */
Himani Chawla4d908332020-08-31 12:30:20 +05301739 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001740 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001742}
1743
Himani Chawla6d2ae152020-09-02 13:11:20 +05301744// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001745// #################################################################################
1746
1747// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301748// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001749
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001750//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001751func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001752 dh.lockDevice.RLock()
1753 pOnuDeviceEntry := dh.pOnuOmciDevice
1754 if aWait && pOnuDeviceEntry == nil {
1755 //keep the read sema short to allow for subsequent write
1756 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001757 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001758 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1759 // so it might be needed to wait here for that event with some timeout
1760 select {
1761 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001762 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001763 return nil
1764 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001765 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001766 // if written now, we can return the written value without sema
1767 return dh.pOnuOmciDevice
1768 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001769 }
mpagenko3af1f032020-06-10 08:53:41 +00001770 dh.lockDevice.RUnlock()
1771 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001772}
1773
Himani Chawla6d2ae152020-09-02 13:11:20 +05301774//setOnuDeviceEntry sets the ONU device entry within the handler
1775func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001776 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001777 dh.lockDevice.Lock()
1778 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001779 dh.pOnuOmciDevice = apDeviceEntry
1780 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001781 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301782 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001783 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001784}
1785
Himani Chawla6d2ae152020-09-02 13:11:20 +05301786//addOnuDeviceEntry creates a new ONU device or returns the existing
1787func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001788 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001789
dbainbri4d3a0dc2020-12-02 00:33:42 +00001790 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001791 if deviceEntry == nil {
1792 /* costum_me_map in python code seems always to be None,
1793 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1794 /* also no 'clock' argument - usage open ...*/
1795 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001796 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001797 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001798 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301799 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001800 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001801 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001802 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001803 // fire deviceEntry ready event to spread to possibly waiting processing
1804 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001805 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001806 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001807 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001808 }
1809 // might be updated with some error handling !!!
1810 return nil
1811}
1812
dbainbri4d3a0dc2020-12-02 00:33:42 +00001813func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1814 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001815 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1816
1817 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001818
dbainbri4d3a0dc2020-12-02 00:33:42 +00001819 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001820 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001821 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001822 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1823 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001824 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001825 if err := dh.storePersistentData(ctx); err != nil {
1826 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001827 log.Fields{"device-id": dh.deviceID, "err": err})
1828 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001829 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001830 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001831 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001832 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1833 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001834 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001835 }
1836 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001837 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001838 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001839
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001840 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001841 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001842 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001843 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 +00001844 log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001845 dh.stopReconciling(ctx, true)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001846 } else {
1847 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001848 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001849 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001850 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1851 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1852 // 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 +00001853 // 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 +00001854 // so let's just try to keep it simple ...
1855 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001856 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001857 if err != nil || device == nil {
1858 //TODO: needs to handle error scenarios
1859 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1860 return errors.New("Voltha Device not found")
1861 }
1862 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001863
dbainbri4d3a0dc2020-12-02 00:33:42 +00001864 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001865 return err
mpagenko3af1f032020-06-10 08:53:41 +00001866 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001867
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001868 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001869
1870 /* this might be a good time for Omci Verify message? */
1871 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001872 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001873 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001874 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001875 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001876
1877 /* give the handler some time here to wait for the OMCi verification result
1878 after Timeout start and try MibUpload FSM anyway
1879 (to prevent stopping on just not supported OMCI verification from ONU) */
1880 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001881 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001882 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001883 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001884 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001885 }
1886
1887 /* In py code it looks earlier (on activate ..)
1888 # Code to Run OMCI Test Action
1889 kwargs_omci_test_action = {
1890 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1891 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1892 }
1893 serial_number = device.serial_number
1894 self._test_request = OmciTestRequest(self.core_proxy,
1895 self.omci_agent, self.device_id,
1896 AniG, serial_number,
1897 self.logical_device_id,
1898 exclusive=False,
1899 **kwargs_omci_test_action)
1900 ...
1901 # Start test requests after a brief pause
1902 if not self._test_request_started:
1903 self._test_request_started = True
1904 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1905 reactor.callLater(tststart, self._test_request.start_collector)
1906
1907 */
1908 /* which is then: in omci_test_request.py : */
1909 /*
1910 def start_collector(self, callback=None):
1911 """
1912 Start the collection loop for an adapter if the frequency > 0
1913
1914 :param callback: (callable) Function to call to collect PM data
1915 """
1916 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1917 if callback is None:
1918 callback = self.perform_test_omci
1919
1920 if self.lc is None:
1921 self.lc = LoopingCall(callback)
1922
1923 if self.default_freq > 0:
1924 self.lc.start(interval=self.default_freq / 10)
1925
1926 def perform_test_omci(self):
1927 """
1928 Perform the initial test request
1929 """
1930 ani_g_entities = self._device.configuration.ani_g_entities
1931 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1932 is not None else None
1933 self._entity_id = ani_g_entities_ids[0]
1934 self.logger.info('perform-test', entity_class=self._entity_class,
1935 entity_id=self._entity_id)
1936 try:
1937 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1938 result = yield self._device.omci_cc.send(frame)
1939 if not result.fields['omci_message'].fields['success_code']:
1940 self.logger.info('Self-Test Submitted Successfully',
1941 code=result.fields[
1942 'omci_message'].fields['success_code'])
1943 else:
1944 raise TestFailure('Test Failure: {}'.format(
1945 result.fields['omci_message'].fields['success_code']))
1946 except TimeoutError as e:
1947 self.deferred.errback(failure.Failure(e))
1948
1949 except Exception as e:
1950 self.logger.exception('perform-test-Error', e=e,
1951 class_id=self._entity_class,
1952 entity_id=self._entity_id)
1953 self.deferred.errback(failure.Failure(e))
1954
1955 */
1956
1957 // PM related heartbeat??? !!!TODO....
1958 //self._heartbeat.enabled = True
1959
mpagenko1cc3cb42020-07-27 15:24:38 +00001960 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1961 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1962 * 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 +05301963 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001964 */
1965 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001966 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001967 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001968 if pMibUlFsm.Is(ulStDisabled) {
1969 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001970 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 +00001971 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301972 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301974 //Determine ONU status and start/re-start MIB Synchronization tasks
1975 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001976 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301977 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001978 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 +00001979 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001980 }
Himani Chawla4d908332020-08-31 12:30:20 +05301981 } else {
1982 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001983 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 +00001984 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301985 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001986 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001987 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001988 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001989 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001990 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001991 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001992 }
1993 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001994 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001995 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001996 }
1997 return nil
1998}
1999
dbainbri4d3a0dc2020-12-02 00:33:42 +00002000func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00002001 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002002 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002003 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002004 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002005
mpagenko900ee4b2020-10-12 11:56:34 +00002006 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2007 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2008 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002009 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002010 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00002011 log.Fields{"device-id": dh.deviceID, "error": err})
2012 // abort: system behavior is just unstable ...
2013 return err
2014 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002015 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002016 _ = 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 +00002017
2018 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
2019 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
2020 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00002021 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002022 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002023 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002024 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002025 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002026 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002027
2028 //TODO!!! remove existing traffic profiles
2029 /* from py code, if TP's exist, remove them - not yet implemented
2030 self._tp = dict()
2031 # Let TP download happen again
2032 for uni_id in self._tp_service_specific_task:
2033 self._tp_service_specific_task[uni_id].clear()
2034 for uni_id in self._tech_profile_download_done:
2035 self._tech_profile_download_done[uni_id].clear()
2036 */
2037
dbainbri4d3a0dc2020-12-02 00:33:42 +00002038 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002039
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002040 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002041
dbainbri4d3a0dc2020-12-02 00:33:42 +00002042 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002043 // abort: system behavior is just unstable ...
2044 return err
2045 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002046 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002047 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002048 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00002049 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002050 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002051 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00002052 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002053 // abort: system behavior is just unstable ...
2054 return err
2055 }
2056 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002057 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002058 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002059 return nil
2060}
2061
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002062func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002063 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2064 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2065 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2066 // and using the stop/reset event should never harm
2067
dbainbri4d3a0dc2020-12-02 00:33:42 +00002068 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002069 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002070 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002071 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2072 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002073 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002074 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002075 }
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002076 pDevEntry.mutexOnuImageStatus.RLock()
2077 if pDevEntry.pOnuImageStatus != nil {
2078 pDevEntry.pOnuImageStatus.CancelProcessing(ctx)
2079 }
2080 pDevEntry.mutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002081
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002082 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002083 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002084 }
2085 //MibDownload may run
2086 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2087 if pMibDlFsm != nil {
2088 _ = pMibDlFsm.Event(dlEvReset)
2089 }
2090 //port lock/unlock FSM's may be active
2091 if dh.pUnlockStateFsm != nil {
2092 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2093 }
2094 if dh.pLockStateFsm != nil {
2095 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2096 }
2097 //techProfile related PonAniConfigFsm FSM may be active
2098 if dh.pOnuTP != nil {
2099 // should always be the case here
2100 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
2101 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08002102 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00002103 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002104 }
mpagenko900ee4b2020-10-12 11:56:34 +00002105 }
2106 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002107 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002108 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00002109 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
2110 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002111 dh.lockVlanConfig.RUnlock()
2112 //reset of all Fsm is always accompanied by global persistency data removal
2113 // no need to remove specific data
2114 pVlanFilterFsm.RequestClearPersistency(false)
2115 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002116 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002117 } else {
2118 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002119 }
2120 }
2121 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002122 if dh.getCollectorIsRunning() {
2123 // Stop collector routine
2124 dh.stopCollector <- true
2125 }
Himani Chawla1472c682021-03-17 17:11:14 +05302126 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302127 dh.stopAlarmManager <- true
2128 }
2129
mpagenko80622a52021-02-09 16:53:23 +00002130 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00002131 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002132 dh.lockUpgradeFsm.RLock()
2133 if dh.pOnuUpradeFsm != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00002134 dh.pOnuUpradeFsm.CancelProcessing(ctx)
mpagenko80622a52021-02-09 16:53:23 +00002135 }
2136 dh.lockUpgradeFsm.RUnlock()
2137
mpagenko7d6bb022021-03-11 15:07:55 +00002138 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002139 return nil
2140}
2141
dbainbri4d3a0dc2020-12-02 00:33:42 +00002142func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2143 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 +05302144
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002145 // store persistent data collected during MIB upload processing
2146 if err := dh.storePersistentData(ctx); err != nil {
2147 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2148 log.Fields{"device-id": dh.deviceID, "err": err})
2149 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002150 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002151 dh.addAllUniPorts(ctx)
2152
mpagenkoa40e99a2020-11-17 13:50:39 +00002153 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2154 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2155 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2156 * disable/enable toggling here to allow traffic
2157 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2158 * like the py comment says:
2159 * # start by locking all the unis till mib sync and initial mib is downloaded
2160 * # this way we can capture the port down/up events when we are ready
2161 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302162
mpagenkoa40e99a2020-11-17 13:50:39 +00002163 // Init Uni Ports to Admin locked state
2164 // *** should generate UniLockStateDone event *****
2165 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002166 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002167 } else { //LockStateFSM already init
2168 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002169 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002170 }
2171}
2172
dbainbri4d3a0dc2020-12-02 00:33:42 +00002173func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2174 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302175 /* Mib download procedure -
2176 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2177 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002178 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002179 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002180 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002181 return
2182 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302183 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2184 if pMibDlFsm != nil {
2185 if pMibDlFsm.Is(dlStDisabled) {
2186 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002187 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 +05302188 // maybe try a FSM reset and then again ... - TODO!!!
2189 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002190 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302191 // maybe use more specific states here for the specific download steps ...
2192 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002193 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302194 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002195 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302196 //Begin MIB data download (running autonomously)
2197 }
2198 }
2199 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002200 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002201 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302202 // maybe try a FSM reset and then again ... - TODO!!!
2203 }
2204 /***** Mib download started */
2205 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002206 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302207 }
2208}
2209
dbainbri4d3a0dc2020-12-02 00:33:42 +00002210func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2211 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302212 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002213 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002214 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002215 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002216 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2217 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2218 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2219 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002220 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302221 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
2222 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002223 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302224 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002225 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302226 }
2227 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002228 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302229 log.Fields{"device-id": dh.deviceID})
2230 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002231 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002232
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002233 if !dh.getCollectorIsRunning() {
2234 // Start PM collector routine
2235 go dh.startCollector(ctx)
2236 }
2237 if !dh.getAlarmManagerIsRunning(ctx) {
2238 go dh.startAlarmManager(ctx)
2239 }
2240
Girish Gowdrae0140f02021-02-02 16:55:09 -08002241 // Initialize classical L2 PM Interval Counters
2242 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2243 // There is no way we should be landing here, but if we do then
2244 // there is nothing much we can do about this other than log error
2245 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2246 }
2247
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002248 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002249
2250 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2251 if pDevEntry == nil {
2252 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2253 return
2254 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002255 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002256 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002257 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002258 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2259 log.Fields{"device-id": dh.deviceID})
2260 go dh.reconcileDeviceTechProf(ctx)
2261 // reconcilement will be continued after ani config is done
2262 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002263 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002264 // *** should generate UniUnlockStateDone event *****
2265 if dh.pUnlockStateFsm == nil {
2266 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2267 } else { //UnlockStateFSM already init
2268 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2269 dh.runUniLockFsm(ctx, false)
2270 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302271 }
2272}
2273
dbainbri4d3a0dc2020-12-02 00:33:42 +00002274func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2275 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302276
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002277 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002278 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002279 raisedTs := time.Now().Unix()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002280 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2281 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002282 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002283 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002284 return
2285 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002286 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002287 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002288 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002289 if err := dh.storePersistentData(ctx); err != nil {
2290 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002291 log.Fields{"device-id": dh.deviceID, "err": err})
2292 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302293 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002294 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 +05302295 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002296 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002297 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302298 }
2299}
2300
dbainbri4d3a0dc2020-12-02 00:33:42 +00002301func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2302 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002303 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002304 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00002305 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
2306 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002307 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002308 }
2309
dbainbri4d3a0dc2020-12-02 00:33:42 +00002310 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002311 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002312 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002313
2314 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002315 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002316
dbainbri4d3a0dc2020-12-02 00:33:42 +00002317 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002318 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002319 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002320 return
2321 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002322 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002323 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002324 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002325 if err := dh.storePersistentData(ctx); err != nil {
2326 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002327 log.Fields{"device-id": dh.deviceID, "err": err})
2328 }
mpagenko900ee4b2020-10-12 11:56:34 +00002329}
2330
dbainbri4d3a0dc2020-12-02 00:33:42 +00002331func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2332 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002333 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002334 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002335 voltha.OperStatus_ACTIVE); err != nil {
2336 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002337 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002338 }
2339
dbainbri4d3a0dc2020-12-02 00:33:42 +00002340 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002341 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002342 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002343 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002344
2345 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002346 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002347
dbainbri4d3a0dc2020-12-02 00:33:42 +00002348 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002349 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002350 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002351 return
2352 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002353 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002354 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002355 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002356 if err := dh.storePersistentData(ctx); err != nil {
2357 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002358 log.Fields{"device-id": dh.deviceID, "err": err})
2359 }
mpagenko900ee4b2020-10-12 11:56:34 +00002360}
2361
dbainbri4d3a0dc2020-12-02 00:33:42 +00002362func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002363 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002364 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002365 // attention: the device reason update is done based on ONU-UNI-Port related activity
2366 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002367 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002368 // 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 +00002369 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302370 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002371 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002372 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002373 }
2374 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002375 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002376 // attention: the device reason update is done based on ONU-UNI-Port related activity
2377 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002378 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002379 // 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 +00002380 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002381 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002382 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302383}
2384
dbainbri4d3a0dc2020-12-02 00:33:42 +00002385func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2386 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002387 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302388 // attention: the device reason update is done based on ONU-UNI-Port related activity
2389 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302390
mpagenkof1fc3862021-02-16 10:09:52 +00002391 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002392 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002393 // which may be the case from some previous actvity on another UNI Port of the ONU
2394 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002395 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2396 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002397 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002398 }
2399 }
2400 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002401 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002402 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002403 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002404 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302405 }
mpagenkof1fc3862021-02-16 10:09:52 +00002406
2407 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2408 //events that request KvStore write
2409 if err := dh.storePersistentData(ctx); err != nil {
2410 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2411 log.Fields{"device-id": dh.deviceID, "err": err})
2412 }
2413 } else {
2414 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2415 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002416 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302417}
2418
Himani Chawla6d2ae152020-09-02 13:11:20 +05302419//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002420func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302421 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002422 case MibDatabaseSync:
2423 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002424 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002425 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002426 case UniLockStateDone:
2427 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002428 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002429 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002430 case MibDownloadDone:
2431 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002432 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002433 }
2434 case UniUnlockStateDone:
2435 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002436 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002437 }
mpagenko900ee4b2020-10-12 11:56:34 +00002438 case UniEnableStateDone:
2439 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002440 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002441 }
2442 case UniDisableStateDone:
2443 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002444 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002445 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002446 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002447 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002448 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002449 }
mpagenkof1fc3862021-02-16 10:09:52 +00002450 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002451 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002452 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002453 }
mpagenkoaa3afe92021-05-21 16:20:58 +00002454 case OmciOnuSwUpgradeDone:
2455 {
2456 dh.upgradeSuccess = true
2457 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002458 default:
2459 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002460 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002461 }
2462 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002463}
2464
dbainbri4d3a0dc2020-12-02 00:33:42 +00002465func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002466 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002467 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302468 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002469 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002470 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002471 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302472 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002473 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002474 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002475 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002476 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002477 //store UniPort with the System-PortNumber key
2478 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002479 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002480 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002481 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2482 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002483 } //error logging already within UniPort method
2484 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002485 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002486 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002487 }
2488 }
2489}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002490
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002491func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2492 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2493 if pDevEntry == nil {
2494 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2495 return
2496 }
2497 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2498 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2499 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2500 for _, mgmtEntityID := range pptpInstKeys {
2501 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2502 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2503 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2504 i++
2505 }
2506 } else {
2507 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2508 }
2509 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2510 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2511 for _, mgmtEntityID := range veipInstKeys {
2512 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2513 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2514 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2515 i++
2516 }
2517 } else {
2518 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2519 }
2520 if i == 0 {
2521 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2522 }
2523}
2524
mpagenko3af1f032020-06-10 08:53:41 +00002525// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002526func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002527 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302528 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002529 // with following remark:
2530 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2531 // # load on the core
2532
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002533 // 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 +00002534
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002535 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002536 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002537 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002538 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302539 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002540 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002541 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002542 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 +00002543 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002544 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002545 }
mpagenko3af1f032020-06-10 08:53:41 +00002546 }
2547 }
2548}
2549
2550// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002551func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002552 // compare enableUniPortStateUpdate() above
2553 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2554 for uniNo, uniPort := range dh.uniEntityMap {
2555 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002556
2557 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002558 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302559 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002560 if !dh.isReconciling() {
2561 //maybe also use getter functions on uniPort - perhaps later ...
2562 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2563 } else {
2564 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2565 }
2566
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002567 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002568 }
2569}
2570
2571// ONU_Active/Inactive announcement on system KAFKA bus
2572// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002573func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002574 var de voltha.DeviceEvent
2575 eventContext := make(map[string]string)
2576 //Populating event context
2577 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002578 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002579 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002580 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302581 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002582 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 +00002583 }
2584 oltSerialNumber := parentDevice.SerialNumber
2585
2586 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2587 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2588 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302589 eventContext["olt-serial-number"] = oltSerialNumber
2590 eventContext["device-id"] = aDeviceID
2591 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002592 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
2593 if deviceEntry := dh.getOnuDeviceEntry(ctx, false); deviceEntry != nil {
2594 deviceEntry.mutexPersOnuConfig.RLock()
2595 eventContext["equipment-id"] = deviceEntry.sOnuPersistentData.PersEquipmentID
2596 deviceEntry.mutexPersOnuConfig.RUnlock()
2597 eventContext["software-version"] = deviceEntry.getActiveImageVersion(ctx)
2598 deviceEntry.mutexPersOnuConfig.RLock()
2599 eventContext["vendor"] = deviceEntry.sOnuPersistentData.PersVendorID
2600 deviceEntry.mutexPersOnuConfig.RUnlock()
2601 eventContext["inactive-software-version"] = deviceEntry.getInactiveImageVersion(ctx)
2602 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2603 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2604 } else {
2605 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2606 log.Fields{"device-id": aDeviceID})
2607 return
2608 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002609
2610 /* Populating device event body */
2611 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302612 de.ResourceId = aDeviceID
2613 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002614 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2615 de.Description = fmt.Sprintf("%s Event - %s - %s",
2616 cEventObjectType, cOnuActivatedEvent, "Raised")
2617 } else {
2618 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2619 de.Description = fmt.Sprintf("%s Event - %s - %s",
2620 cEventObjectType, cOnuActivatedEvent, "Cleared")
2621 }
2622 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002623 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2624 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302625 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002626 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002627 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302628 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002629}
2630
Himani Chawla4d908332020-08-31 12:30:20 +05302631// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002632func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002633 chLSFsm := make(chan Message, 2048)
2634 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302635 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002636 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002637 sFsmName = "LockStateFSM"
2638 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002639 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002640 sFsmName = "UnLockStateFSM"
2641 }
mpagenko3af1f032020-06-10 08:53:41 +00002642
dbainbri4d3a0dc2020-12-02 00:33:42 +00002643 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002644 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002645 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002646 return
2647 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002648 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002649 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002650 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302651 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002652 dh.pLockStateFsm = pLSFsm
2653 } else {
2654 dh.pUnlockStateFsm = pLSFsm
2655 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002656 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002657 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002658 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002659 }
2660}
2661
2662// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002663func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002664 /* Uni Port lock/unlock procedure -
2665 ***** should run via 'adminDone' state and generate the argument requested event *****
2666 */
2667 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302668 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002669 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2670 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2671 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002672 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302673 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002674 }
2675 } else {
2676 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2677 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2678 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002679 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302680 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002681 }
2682 }
2683 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002684 if pLSStatemachine.Is(uniStDisabled) {
2685 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002686 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002687 // maybe try a FSM reset and then again ... - TODO!!!
2688 } else {
2689 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002690 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002691 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002692 }
2693 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002694 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002695 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002696 // maybe try a FSM reset and then again ... - TODO!!!
2697 }
2698 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002699 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002700 // maybe try a FSM reset and then again ... - TODO!!!
2701 }
2702}
2703
mpagenko80622a52021-02-09 16:53:23 +00002704// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002705func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002706 //in here lockUpgradeFsm is already locked
2707 chUpgradeFsm := make(chan Message, 2048)
2708 var sFsmName = "OnuSwUpgradeFSM"
2709 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002710 if apDevEntry.PDevOmciCC == nil {
2711 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2712 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002713 }
mpagenko15ff4a52021-03-02 10:09:20 +00002714 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002715 sFsmName, chUpgradeFsm)
2716 if dh.pOnuUpradeFsm != nil {
2717 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2718 if pUpgradeStatemachine != nil {
2719 if pUpgradeStatemachine.Is(upgradeStDisabled) {
mpagenkoaa3afe92021-05-21 16:20:58 +00002720 dh.upgradeSuccess = false //for start of upgrade processing reset the last indication
mpagenko80622a52021-02-09 16:53:23 +00002721 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2722 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2723 // maybe try a FSM reset and then again ... - TODO!!!
2724 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2725 }
2726 /***** LockStateFSM started */
2727 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2728 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2729 } else {
2730 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2731 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2732 // maybe try a FSM reset and then again ... - TODO!!!
2733 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2734 }
2735 } else {
2736 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2737 // maybe try a FSM reset and then again ... - TODO!!!
2738 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2739 }
2740 } else {
2741 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2742 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2743 }
2744 return nil
2745}
2746
2747// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2748func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2749 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2750 "device-id": dh.deviceID})
2751 dh.lockUpgradeFsm.Lock()
2752 defer dh.lockUpgradeFsm.Unlock()
2753 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2754}
2755
mpagenko15ff4a52021-03-02 10:09:20 +00002756// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2757func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2758 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2759 if pDevEntry == nil {
2760 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2761 return
2762 }
2763
2764 dh.lockUpgradeFsm.RLock()
2765 defer dh.lockUpgradeFsm.RUnlock()
2766 if dh.pOnuUpradeFsm != nil {
2767 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2768 if pUpgradeStatemachine != nil {
2769 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2770 // (some manual forced commit could do without)
mpagenko1f8e8822021-06-25 14:10:21 +00002771 upgradeState := pUpgradeStatemachine.Current()
2772 if (upgradeState == upgradeStWaitForCommit) ||
2773 (upgradeState == upgradeStRequestingActivate) {
2774 // also include upgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00002775 // 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 +00002776 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00002777 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
2778 if errImg != nil {
2779 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
2780 log.Fields{"device-id": dh.deviceID})
2781 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
mpagenko15ff4a52021-03-02 10:09:20 +00002782 return
2783 }
mpagenko1f8e8822021-06-25 14:10:21 +00002784 if activeImageID == dh.pOnuUpradeFsm.inactiveImageMeID {
2785 if (upgradeState == upgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
2786 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
2787 if err := pUpgradeStatemachine.Event(upgradeEvActivationDone); err != nil {
2788 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
2789 return
2790 }
2791 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
2792 "state": upgradeState, "device-id": dh.deviceID})
2793 } else {
2794 //FSM in waitForCommit or (upgradeStRequestingActivate [lost ActivateResp] and commit allowed)
2795 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2796 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2797 return
2798 }
2799 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2800 "state": upgradeState, "device-id": dh.deviceID})
2801 }
2802 } else {
2803 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit/on ActivateResponse, but load did not start with expected image Id",
2804 log.Fields{"device-id": dh.deviceID})
2805 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2806 return
2807 }
mpagenko15ff4a52021-03-02 10:09:20 +00002808 } else {
2809 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2810 log.Fields{"device-id": dh.deviceID})
2811 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2812 return
2813 }
mpagenko183647c2021-06-08 15:25:04 +00002814 } else {
2815 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2816 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2817 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2818 if dh.pOnuUpradeFsm.inactiveImageMeID == activeImageID {
2819 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2820 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2821 dh.pOnuUpradeFsm.SetImageState(ctx, voltha.ImageState_IMAGE_ACTIVE)
2822 }
2823 }
mpagenko15ff4a52021-03-02 10:09:20 +00002824 }
2825 }
2826 } else {
2827 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2828 }
2829}
2830
Himani Chawla6d2ae152020-09-02 13:11:20 +05302831//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002832func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002833
2834 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002835 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07002836 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00002837 kvbackend := &db.Backend{
2838 Client: dh.pOpenOnuAc.kvClient,
2839 StoreType: dh.pOpenOnuAc.KVStoreType,
2840 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002841 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002842 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2843 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002844
mpagenkoaf801632020-07-03 10:00:42 +00002845 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002846}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002847func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302848 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002849
mpagenkodff5dda2020-08-28 11:52:01 +00002850 for _, field := range flow.GetOfbFields(apFlowItem) {
2851 switch field.Type {
2852 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2853 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002854 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002855 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2856 }
mpagenko01e726e2020-10-23 09:45:29 +00002857 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002858 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2859 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302860 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002861 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302862 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2863 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002864 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2865 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002866 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2867 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302868 return
mpagenkodff5dda2020-08-28 11:52:01 +00002869 }
2870 }
mpagenko01e726e2020-10-23 09:45:29 +00002871 */
mpagenkodff5dda2020-08-28 11:52:01 +00002872 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2873 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302874 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002875 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302876 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002877 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302878 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002879 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002880 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302881 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002882 }
2883 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2884 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302885 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002886 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002887 "PCP": loAddPcp})
2888 }
2889 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2890 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002891 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002892 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2893 }
2894 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2895 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002896 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002897 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2898 }
2899 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2900 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002901 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002902 "IPv4-DST": field.GetIpv4Dst()})
2903 }
2904 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2905 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002906 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002907 "IPv4-SRC": field.GetIpv4Src()})
2908 }
2909 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2910 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002911 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002912 "Metadata": field.GetTableMetadata()})
2913 }
2914 /*
2915 default:
2916 {
2917 //all other entires ignored
2918 }
2919 */
2920 }
2921 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302922}
mpagenkodff5dda2020-08-28 11:52:01 +00002923
dbainbri4d3a0dc2020-12-02 00:33:42 +00002924func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002925 for _, action := range flow.GetActions(apFlowItem) {
2926 switch action.Type {
2927 /* not used:
2928 case of.OfpActionType_OFPAT_OUTPUT:
2929 {
mpagenko01e726e2020-10-23 09:45:29 +00002930 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002931 "Output": action.GetOutput()})
2932 }
2933 */
2934 case of.OfpActionType_OFPAT_PUSH_VLAN:
2935 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002936 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002937 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2938 }
2939 case of.OfpActionType_OFPAT_SET_FIELD:
2940 {
2941 pActionSetField := action.GetSetField()
2942 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002943 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002944 "OxcmClass": pActionSetField.Field.OxmClass})
2945 }
2946 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302947 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002948 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302949 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002950 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302951 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002952 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302953 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002954 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002955 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002956 "Type": pActionSetField.Field.GetOfbField().Type})
2957 }
2958 }
2959 /*
2960 default:
2961 {
2962 //all other entires ignored
2963 }
2964 */
2965 }
2966 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302967}
2968
2969//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
ozgecanetsia82b91a62021-05-21 18:54:49 +03002970func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort,
2971 apFlowMetaData *voltha.FlowMetadata) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302972 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2973 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2974 var loAddPcp, loSetPcp uint8
2975 var loIPProto uint32
2976 /* the TechProfileId is part of the flow Metadata - compare also comment within
2977 * OLT-Adapter:openolt_flowmgr.go
2978 * Metadata 8 bytes:
2979 * Most Significant 2 Bytes = Inner VLAN
2980 * Next 2 Bytes = Tech Profile ID(TPID)
2981 * Least Significant 4 Bytes = Port ID
2982 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2983 * subscriber related flows.
2984 */
2985
dbainbri4d3a0dc2020-12-02 00:33:42 +00002986 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302987 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002988 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302989 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002990 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302991 }
mpagenko551a4d42020-12-08 18:09:20 +00002992 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002993 loCookie := apFlowItem.GetCookie()
2994 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002995 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002996 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302997
dbainbri4d3a0dc2020-12-02 00:33:42 +00002998 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002999 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303000 if loIPProto == 2 {
3001 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3002 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003003 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
3004 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303005 return nil
3006 }
mpagenko01e726e2020-10-23 09:45:29 +00003007 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003008 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003009
3010 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003011 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003012 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
3013 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3014 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3015 //TODO!!: Use DeviceId within the error response to rwCore
3016 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00003017 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003018 }
3019 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003020 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003021 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3022 } else {
3023 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3024 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3025 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303026 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003027 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003028 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003029 }
mpagenko9a304ea2020-12-16 15:54:01 +00003030
ozgecanetsia82b91a62021-05-21 18:54:49 +03003031 var meter *voltha.OfpMeterConfig
3032 if apFlowMetaData != nil {
3033 meter = apFlowMetaData.Meters[0]
3034 }
mpagenko2f487262021-08-23 15:59:06 +00003035 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3036 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3037 // when different rules are requested concurrently for the same uni
3038 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3039 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3040 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
3041 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID, "tpID": loTpID, "uniID": apUniPort.uniID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303042 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenko2f487262021-08-23 15:59:06 +00003043 //SetUniFlowParams() may block on some rule that is suspended-to-add
3044 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
mpagenkof1fc3862021-02-16 10:09:52 +00003045 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003046 loMatchVlan, loSetVlan, loSetPcp, false, meter)
mpagenko2f487262021-08-23 15:59:06 +00003047 dh.lockVlanConfig.RUnlock()
3048 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
mpagenkof1fc3862021-02-16 10:09:52 +00003049 return err
mpagenkodff5dda2020-08-28 11:52:01 +00003050 }
mpagenko2f487262021-08-23 15:59:06 +00003051 dh.lockVlanConfig.RUnlock()
3052 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko37047052021-07-27 10:01:29 +00003053 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003054 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false, meter)
mpagenko37047052021-07-27 10:01:29 +00003055 dh.lockVlanConfig.Unlock()
mpagenko2f487262021-08-23 15:59:06 +00003056 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
mpagenko37047052021-07-27 10:01:29 +00003057 return err
mpagenko01e726e2020-10-23 09:45:29 +00003058}
3059
3060//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00003061func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00003062 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3063 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3064 //no extra check is done on the rule parameters
3065 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3066 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3067 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3068 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003069 // - 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 +00003070 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003071 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003072
3073 /* TT related temporary workaround - should not be needed anymore
3074 for _, field := range flow.GetOfbFields(apFlowItem) {
3075 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3076 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00003077 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003078 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3079 if loIPProto == 2 {
3080 // 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 +00003081 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00003082 log.Fields{"device-id": dh.deviceID})
3083 return nil
3084 }
3085 }
3086 } //for all OfbFields
3087 */
3088
mpagenko9a304ea2020-12-16 15:54:01 +00003089 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003090 dh.lockVlanConfig.RLock()
3091 defer dh.lockVlanConfig.RUnlock()
mpagenko2f487262021-08-23 15:59:06 +00003092 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.deviceID, "uniID": apUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +00003093 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003094 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00003095 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003096 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00003097 log.Fields{"device-id": dh.deviceID})
3098 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003099 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00003100 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00003101
mpagenko01e726e2020-10-23 09:45:29 +00003102 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00003103}
3104
Himani Chawla26e555c2020-08-31 12:30:20 +05303105// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003106// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko37047052021-07-27 10:01:29 +00003107// precondition: dh.lockVlanConfig is locked by the caller!
mpagenko551a4d42020-12-08 18:09:20 +00003108func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003109 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
mpagenkodff5dda2020-08-28 11:52:01 +00003110 chVlanFilterFsm := make(chan Message, 2048)
3111
dbainbri4d3a0dc2020-12-02 00:33:42 +00003112 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003113 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003114 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303115 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003116 }
3117
dbainbri4d3a0dc2020-12-02 00:33:42 +00003118 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00003119 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003120 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter)
mpagenkodff5dda2020-08-28 11:52:01 +00003121 if pVlanFilterFsm != nil {
mpagenko37047052021-07-27 10:01:29 +00003122 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3123 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Himani Chawla26e555c2020-08-31 12:30:20 +05303124 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003125 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3126 if pVlanFilterStatemachine != nil {
3127 if pVlanFilterStatemachine.Is(vlanStDisabled) {
3128 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003129 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05303130 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003131 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303132 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003133 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05303134 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3135 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003136 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003137 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003138 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303139 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003140 }
3141 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003142 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003143 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303144 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003145 }
3146 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003147 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003148 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05303149 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003150 }
3151 return nil
3152}
3153
mpagenkofc4f56e2020-11-04 17:17:49 +00003154//VerifyVlanConfigRequest checks on existence of a given uniPort
3155// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003156func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003157 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
3158 var pCurrentUniPort *onuUniPort
3159 for _, uniPort := range dh.uniEntityMap {
3160 // only if this port is validated for operState transfer
3161 if uniPort.uniID == uint8(aUniID) {
3162 pCurrentUniPort = uniPort
3163 break //found - end search loop
3164 }
3165 }
3166 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003167 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00003168 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
3169 return
3170 }
mpagenko551a4d42020-12-08 18:09:20 +00003171 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003172}
3173
mpagenkodff5dda2020-08-28 11:52:01 +00003174//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00003175func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003176 //TODO!! verify and start pending flow configuration
3177 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3178 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003179
3180 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303181 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003182 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003183 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
3184 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3185 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003186 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
3187 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
3188 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
3189 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
3190 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3191 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3192 } else {
3193 /***** UniVlanConfigFsm continued */
3194 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
3195 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3196 "UniPort": apUniPort.portNo})
3197 }
3198 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
3199 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
3200 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3201 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3202 } else {
3203 /***** UniVlanConfigFsm continued */
3204 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3205 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3206 "UniPort": apUniPort.portNo})
3207 }
mpagenkodff5dda2020-08-28 11:52:01 +00003208 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003209 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3210 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003211 "UniPort": apUniPort.portNo})
3212 }
3213 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003214 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3215 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3216 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003217 }
3218 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003219 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003220 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003221 }
mpagenkof1fc3862021-02-16 10:09:52 +00003222 } else {
3223 dh.lockVlanConfig.RUnlock()
3224 }
mpagenkodff5dda2020-08-28 11:52:01 +00003225}
3226
3227//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3228// 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 +00003229func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3230 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003231 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3232 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003233 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303234 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003235 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003236}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003237
mpagenkof1fc3862021-02-16 10:09:52 +00003238//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3239func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3240 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3241 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3242 // obviously then parallel processing on the cancel must be avoided
3243 // deadline context to ensure completion of background routines waited for
3244 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3245 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3246 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3247
3248 aPDevEntry.resetKvProcessingErrorIndication()
3249 var wg sync.WaitGroup
3250 wg.Add(1) // for the 1 go routine to finish
3251
3252 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3253 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3254
3255 return aPDevEntry.getKvProcessingErrorIndication()
3256}
3257
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003258//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3259//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003260func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3261 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003262
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003263 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003264 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003265 return nil
3266 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003267 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003268
dbainbri4d3a0dc2020-12-02 00:33:42 +00003269 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003270 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003271 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003272 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3273 }
3274 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3275
mpagenkof1fc3862021-02-16 10:09:52 +00003276 if aWriteToKvStore {
3277 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3278 }
3279 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003280}
3281
dbainbri4d3a0dc2020-12-02 00:33:42 +00003282func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003283 defer cancel() //ensure termination of context (may be pro forma)
3284 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003285 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003286 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003287}
3288
dbainbri4d3a0dc2020-12-02 00:33:42 +00003289func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003290
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003291 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003292 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003293 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003294 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3295 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003296 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003297 return err
3298 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003299 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003300 return nil
3301 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003302 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003303 return nil
3304}
3305
dbainbri4d3a0dc2020-12-02 00:33:42 +00003306func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3307 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003308 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003309 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003310 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3311 }
mpagenkof1fc3862021-02-16 10:09:52 +00003312 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003313}
3314
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003315// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003316// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003317func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3318 dh.lockDevice.RLock()
3319 defer dh.lockDevice.RUnlock()
3320 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3321 return uniPort.entityID, nil
3322 }
3323 return 0, errors.New("error-fetching-uni-port")
3324}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003325
3326// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003327func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3328 var errorsList []error
3329 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 -08003330
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003331 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3332 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3333 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3334
3335 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3336 // successfully.
3337 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3338 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3339 if len(errorsList) > 0 {
3340 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3341 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003342 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003343 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3344 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003345}
3346
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003347func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3348 var err error
3349 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003350 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003351
3352 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3353 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3354 errorsList = append(errorsList, err)
3355 }
3356 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003357 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003358
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003359 return errorsList
3360}
3361
3362func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3363 var err error
3364 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003365 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003366 // Check if group metric related config is updated
3367 for _, v := range pmConfigs.Groups {
3368 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3369 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3370 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3371
3372 if ok && m.frequency != v.GroupFreq {
3373 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3374 errorsList = append(errorsList, err)
3375 }
3376 }
3377 if ok && m.enabled != v.Enabled {
3378 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3379 errorsList = append(errorsList, err)
3380 }
3381 }
3382 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003383 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003384 return errorsList
3385}
3386
3387func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3388 var err error
3389 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003390 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003391 // Check if standalone metric related config is updated
3392 for _, v := range pmConfigs.Metrics {
3393 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003394 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003395 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3396
3397 if ok && m.frequency != v.SampleFreq {
3398 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3399 errorsList = append(errorsList, err)
3400 }
3401 }
3402 if ok && m.enabled != v.Enabled {
3403 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3404 errorsList = append(errorsList, err)
3405 }
3406 }
3407 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003408 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003409 return errorsList
3410}
3411
3412// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003413func (dh *deviceHandler) startCollector(ctx context.Context) {
3414 logger.Debugf(ctx, "startingCollector")
3415
3416 // Start routine to process OMCI GET Responses
3417 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303418 // Create Extended Frame PM ME
3419 go dh.pOnuMetricsMgr.createEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003420 // Initialize the next metric collection time.
3421 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3422 // reset like onu rebooted.
3423 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003424 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003425 for {
3426 select {
3427 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003428 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003429 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003430 // Stop the L2 PM FSM
3431 go func() {
3432 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3433 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3434 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3435 }
3436 } else {
3437 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3438 }
3439 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003440 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3441 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3442 }
3443 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3444 dh.pOnuMetricsMgr.stopTicks <- true
3445 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003446
Girish Gowdrae09a6202021-01-12 18:10:59 -08003447 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003448 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3449 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3450 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3451 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3452 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003453 // Update the next metric collection time.
3454 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003455 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003456 } else {
3457 if dh.pmConfigs.Grouped { // metrics are managed as a group
3458 // parse through the group and standalone metrics to see it is time to collect their metrics
3459 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003460
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003461 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3462 // 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 -08003463 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3464 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003465 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3466 }
3467 }
3468 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3469 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3470 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3471 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3472 }
3473 }
3474 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3475
3476 // parse through the group and update the next metric collection time
3477 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3478 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3479 // 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 -08003480 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3481 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003482 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3483 }
3484 }
3485 // parse through the standalone metrics and update the next metric collection time
3486 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3487 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3488 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3489 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3490 }
3491 }
3492 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3493 } /* else { // metrics are not managed as a group
3494 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3495 } */
3496 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003497 }
3498 }
3499}
kesavandfdf77632021-01-26 23:40:33 -05003500
3501func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3502
3503 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3504 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3505}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003506
Himani Chawla43f95ff2021-06-03 00:24:12 +05303507func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3508 if dh.pOnuMetricsMgr == nil {
3509 return &extension.SingleGetValueResponse{
3510 Response: &extension.GetValueResponse{
3511 Status: extension.GetValueResponse_ERROR,
3512 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3513 },
3514 }
3515 }
3516 resp := dh.pOnuMetricsMgr.collectEthernetFrameExtendedPMCounters(ctx)
3517 return resp
3518}
3519
mpagenkof1fc3862021-02-16 10:09:52 +00003520func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3521 if pFsm == nil {
3522 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003523 }
mpagenkof1fc3862021-02-16 10:09:52 +00003524 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003525}
3526
mpagenkof1fc3862021-02-16 10:09:52 +00003527func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3528 var pFsm *fsm.FSM
3529 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3530 switch omciFsm {
3531 case cUploadFsm:
3532 {
3533 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3534 }
3535 case cDownloadFsm:
3536 {
3537 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3538 }
3539 case cUniLockFsm:
3540 {
3541 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3542 }
3543 case cUniUnLockFsm:
3544 {
3545 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3546 }
3547 case cL2PmFsm:
3548 {
3549 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3550 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3551 } else {
3552 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003553 }
3554 }
mpagenko80622a52021-02-09 16:53:23 +00003555 case cOnuUpgradeFsm:
3556 {
3557 dh.lockUpgradeFsm.RLock()
3558 defer dh.lockUpgradeFsm.RUnlock()
3559 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3560 }
mpagenkof1fc3862021-02-16 10:09:52 +00003561 default:
3562 {
3563 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3564 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3565 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003566 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003567 }
mpagenkof1fc3862021-02-16 10:09:52 +00003568 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003569}
3570
mpagenkof1fc3862021-02-16 10:09:52 +00003571func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3572 for _, v := range dh.pOnuTP.pAniConfigFsm {
3573 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003574 return false
3575 }
3576 }
3577 return true
3578}
3579
mpagenkof1fc3862021-02-16 10:09:52 +00003580func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3581 dh.lockVlanConfig.RLock()
3582 defer dh.lockVlanConfig.RUnlock()
3583 for _, v := range dh.UniVlanConfigFsmMap {
3584 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3585 return false
3586 }
3587 }
3588 return true //FSM not active - so there is no activity on omci
3589}
3590
3591func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3592 dh.lockVlanConfig.RLock()
3593 defer dh.lockVlanConfig.RUnlock()
3594 for _, v := range dh.UniVlanConfigFsmMap {
3595 if v.pAdaptFsm.pFsm != nil {
3596 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3597 return true //there is at least one VLAN FSM with some active configuration
3598 }
3599 }
3600 }
3601 return false //there is no VLAN FSM with some active configuration
3602}
3603
3604func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3605 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3606 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3607 return false
3608 }
3609 }
3610 // a further check is done to identify, if at least some data traffic related configuration exists
3611 // 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])
3612 return dh.checkUserServiceExists(ctx)
3613}
3614
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003615func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3616 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3617 if err := dh.resetFsms(ctx, false); err != nil {
3618 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3619 // TODO: fatal error reset ONU, delete deviceHandler!
3620 return
3621 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003622 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003623 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003624}
3625
3626func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3627 dh.mutexCollectorFlag.Lock()
3628 dh.collectorIsRunning = flagValue
3629 dh.mutexCollectorFlag.Unlock()
3630}
3631
3632func (dh *deviceHandler) getCollectorIsRunning() bool {
3633 dh.mutexCollectorFlag.RLock()
3634 flagValue := dh.collectorIsRunning
3635 dh.mutexCollectorFlag.RUnlock()
3636 return flagValue
3637}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303638
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303639func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3640 dh.mutextAlarmManagerFlag.Lock()
3641 dh.alarmManagerIsRunning = flagValue
3642 dh.mutextAlarmManagerFlag.Unlock()
3643}
3644
Himani Chawla1472c682021-03-17 17:11:14 +05303645func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303646 dh.mutextAlarmManagerFlag.RLock()
3647 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303648 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303649 dh.mutextAlarmManagerFlag.RUnlock()
3650 return flagValue
3651}
3652
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303653func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3654 logger.Debugf(ctx, "startingAlarmManager")
3655
3656 // Start routine to process OMCI GET Responses
3657 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303658 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303659 if stop := <-dh.stopAlarmManager; stop {
3660 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303661 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303662 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303663 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3664 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3665 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303666 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303667 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303668 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3669 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303670 }
3671}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003672
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003673func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003674 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003675
Maninder7961d722021-06-16 22:10:28 +05303676 connectStatus := voltha.ConnectStatus_UNREACHABLE
3677 operState := voltha.OperStatus_UNKNOWN
3678
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003679 if !dh.isReconciling() {
3680 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003681 logger.Debugw(ctx, "wait for channel signal or timeout",
3682 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003683 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003684 case success := <-dh.chReconcilingFinished:
3685 if success {
Maninderb5187552021-03-23 22:23:42 +05303686 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3687 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3688 log.Fields{"device-id": dh.deviceID})
3689 } else {
Maninderb5187552021-03-23 22:23:42 +05303690 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3691 connectStatus = voltha.ConnectStatus_REACHABLE
3692 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3693 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3694 operState = voltha.OperStatus_ACTIVE
3695 } else {
3696 operState = voltha.OperStatus_ACTIVATING
3697 }
3698 }
3699 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3700 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3701 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3702 operState = voltha.OperStatus_DISCOVERED
3703 }
3704
3705 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303706 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003707 logger.Debugw(ctx, "reconciling has been finished in time",
3708 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303709 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, operState); err != nil {
3710 logger.Errorw(ctx, "unable to update device state to core",
3711 log.Fields{"device-id": dh.deviceID, "Err": err})
3712 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003713 } else {
Maninderb5187552021-03-23 22:23:42 +05303714 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003715 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303716
3717 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3718 logger.Errorw(ctx, "No valid OnuDevice",
3719 log.Fields{"device-id": dh.deviceID})
3720 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3721 connectStatus = voltha.ConnectStatus_REACHABLE
3722 }
3723
3724 dh.deviceReconcileFailedUpdate(ctx, drReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003725 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003726 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003727 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3728 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303729
3730 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3731 logger.Errorw(ctx, "No valid OnuDevice",
3732 log.Fields{"device-id": dh.deviceID})
3733 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3734 connectStatus = voltha.ConnectStatus_REACHABLE
3735 }
3736
3737 dh.deviceReconcileFailedUpdate(ctx, drReconcileMaxTimeout, connectStatus)
3738
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003739 }
3740 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003741 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003742 dh.mutexReconcilingFlag.Unlock()
3743 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003744 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003745 dh.mutexReconcilingFlag.Lock()
3746 if skipOnuConfig {
3747 dh.reconciling = cSkipOnuConfigReconciling
3748 } else {
3749 dh.reconciling = cOnuConfigReconciling
3750 }
3751 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003752}
3753
Girish Gowdra50e56422021-06-01 16:46:04 -07003754func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool) {
3755 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID, "success": success})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003756 if dh.isReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07003757 dh.chReconcilingFinished <- success
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003758 } else {
3759 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3760 }
3761}
3762
3763func (dh *deviceHandler) isReconciling() bool {
3764 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003765 defer dh.mutexReconcilingFlag.RUnlock()
3766 return dh.reconciling != cNoReconciling
3767}
3768
3769func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3770 dh.mutexReconcilingFlag.RLock()
3771 defer dh.mutexReconcilingFlag.RUnlock()
3772 return dh.reconciling == cSkipOnuConfigReconciling
3773}
3774
3775func (dh *deviceHandler) setDeviceReason(value uint8) {
3776 dh.mutexDeviceReason.Lock()
3777 dh.deviceReason = value
3778 dh.mutexDeviceReason.Unlock()
3779}
3780
3781func (dh *deviceHandler) getDeviceReason() uint8 {
3782 dh.mutexDeviceReason.RLock()
3783 value := dh.deviceReason
3784 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003785 return value
3786}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003787
3788func (dh *deviceHandler) getDeviceReasonString() string {
3789 return deviceReasonMap[dh.getDeviceReason()]
3790}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003791
3792func (dh *deviceHandler) setReconcilingFlows(value bool) {
3793 dh.mutexReconcilingFlowsFlag.Lock()
3794 dh.reconcilingFlows = value
3795 dh.mutexReconcilingFlowsFlag.Unlock()
3796}
3797
3798func (dh *deviceHandler) isReconcilingFlows() bool {
3799 dh.mutexReconcilingFlowsFlag.RLock()
3800 value := dh.reconcilingFlows
3801 dh.mutexReconcilingFlowsFlag.RUnlock()
3802 return value
3803}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003804
3805func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3806 dh.mutexReadyForOmciConfig.Lock()
3807 dh.readyForOmciConfig = flagValue
3808 dh.mutexReadyForOmciConfig.Unlock()
3809}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003810func (dh *deviceHandler) isReadyForOmciConfig() bool {
3811 dh.mutexReadyForOmciConfig.RLock()
3812 flagValue := dh.readyForOmciConfig
3813 dh.mutexReadyForOmciConfig.RUnlock()
3814 return flagValue
3815}
Maninder7961d722021-06-16 22:10:28 +05303816
3817func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
3818 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
3819 logger.Errorw(ctx, "unable to update device reason to core",
3820 log.Fields{"device-id": dh.deviceID, "Err": err})
3821 }
3822
3823 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
3824 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, voltha.OperStatus_RECONCILING_FAILED); err != nil {
3825 logger.Errorw(ctx, "unable to update device state to core",
3826 log.Fields{"device-id": dh.deviceID, "Err": err})
3827 }
3828}