blob: 75e6213e74569d88d3a8d912fea80bb229933a33 [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
mpagenko38662d02021-08-11 09:45:19 +000049// Constants for timeouts
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000050const (
mpagenko38662d02021-08-11 09:45:19 +000051 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000052)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000053
mpagenko1cc3cb42020-07-27 15:24:38 +000054const (
55 // events of Device FSM
56 devEvDeviceInit = "devEvDeviceInit"
57 devEvGrpcConnected = "devEvGrpcConnected"
58 devEvGrpcDisconnected = "devEvGrpcDisconnected"
59 devEvDeviceUpInd = "devEvDeviceUpInd"
60 devEvDeviceDownInd = "devEvDeviceDownInd"
61)
62const (
63 // states of Device FSM
64 devStNull = "devStNull"
65 devStDown = "devStDown"
66 devStInit = "devStInit"
67 devStConnected = "devStConnected"
68 devStUp = "devStUp"
69)
70
Holger Hildebrandt24d51952020-05-04 14:03:42 +000071//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
72const (
Himani Chawla4d908332020-08-31 12:30:20 +053073 pon = voltha.EventSubCategory_PON
74 //olt = voltha.EventSubCategory_OLT
75 //ont = voltha.EventSubCategory_ONT
76 //onu = voltha.EventSubCategory_ONU
77 //nni = voltha.EventSubCategory_NNI
78 //service = voltha.EventCategory_SERVICE
79 //security = voltha.EventCategory_SECURITY
80 equipment = voltha.EventCategory_EQUIPMENT
81 //processing = voltha.EventCategory_PROCESSING
82 //environment = voltha.EventCategory_ENVIRONMENT
83 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000084)
85
86const (
87 cEventObjectType = "ONU"
88)
89const (
90 cOnuActivatedEvent = "ONU_ACTIVATED"
91)
92
Holger Hildebrandt10d98192021-01-27 15:29:31 +000093type usedOmciConfigFsms int
94
95const (
96 cUploadFsm usedOmciConfigFsms = iota
97 cDownloadFsm
98 cUniLockFsm
99 cUniUnLockFsm
100 cAniConfigFsm
101 cUniVlanConfigFsm
Girish Gowdrae0140f02021-02-02 16:55:09 -0800102 cL2PmFsm
mpagenko80622a52021-02-09 16:53:23 +0000103 cOnuUpgradeFsm
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000104)
105
mpagenkof1fc3862021-02-16 10:09:52 +0000106type omciIdleCheckStruct struct {
107 omciIdleCheckFunc func(*deviceHandler, context.Context, usedOmciConfigFsms, string) bool
108 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000109}
110
mpagenkof1fc3862021-02-16 10:09:52 +0000111var fsmOmciIdleStateFuncMap = map[usedOmciConfigFsms]omciIdleCheckStruct{
112 cUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibUlFsmIdleState},
113 cDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibDlFsmIdleState},
114 cUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
115 cUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
116 cAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, cAniFsmIdleState},
117 cUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, cVlanFsmIdleState},
118 cL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cL2PmFsmIdleState},
mpagenko80622a52021-02-09 16:53:23 +0000119 cOnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cOnuUpgradeFsmIdleState},
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000120}
121
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000122const (
123 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000124 drUnset = 0
125 drActivatingOnu = 1
126 drStartingOpenomci = 2
127 drDiscoveryMibsyncComplete = 3
128 drInitialMibDownloaded = 4
129 drTechProfileConfigDownloadSuccess = 5
130 drOmciFlowsPushed = 6
131 drOmciAdminLock = 7
132 drOnuReenabled = 8
133 drStoppingOpenomci = 9
134 drRebooting = 10
135 drOmciFlowsDeleted = 11
136 drTechProfileConfigDeleteSuccess = 12
Maninder7961d722021-06-16 22:10:28 +0530137 drReconcileFailed = 13
138 drReconcileMaxTimeout = 14
139 drReconcileCanceled = 15
Girish Gowdra50e56422021-06-01 16:46:04 -0700140 drTechProfileConfigDownloadFailed = 16
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000141)
142
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000143var deviceReasonMap = map[uint8]string{
144 drUnset: "unset",
145 drActivatingOnu: "activating-onu",
146 drStartingOpenomci: "starting-openomci",
147 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
148 drInitialMibDownloaded: "initial-mib-downloaded",
149 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
Girish Gowdra50e56422021-06-01 16:46:04 -0700150 drTechProfileConfigDownloadFailed: "tech-profile-config-download-failed",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000151 drOmciFlowsPushed: "omci-flows-pushed",
152 drOmciAdminLock: "omci-admin-lock",
153 drOnuReenabled: "onu-reenabled",
154 drStoppingOpenomci: "stopping-openomci",
155 drRebooting: "rebooting",
156 drOmciFlowsDeleted: "omci-flows-deleted",
157 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
Maninder7961d722021-06-16 22:10:28 +0530158 drReconcileFailed: "reconcile-failed",
159 drReconcileMaxTimeout: "reconcile-max-timeout",
160 drReconcileCanceled: "reconciling-canceled",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000161}
162
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000163const (
164 cNoReconciling = iota
165 cOnuConfigReconciling
166 cSkipOnuConfigReconciling
167)
168
Himani Chawla6d2ae152020-09-02 13:11:20 +0530169//deviceHandler will interact with the ONU ? device.
170type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000171 deviceID string
172 DeviceType string
173 adminState string
174 device *voltha.Device
175 logicalDeviceID string
176 ProxyAddressID string
177 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530178 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000179 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000180
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000181 coreProxy adapterif.CoreProxy
182 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530183 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000184
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800185 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800186
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000187 pOpenOnuAc *OpenONUAC
188 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530189 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000190 deviceEntrySet chan bool //channel for DeviceEntry set event
191 pOnuOmciDevice *OnuDeviceEntry
192 pOnuTP *onuUniTechProf
193 pOnuMetricsMgr *onuMetricsManager
194 pAlarmMgr *onuAlarmManager
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700195 pSelfTestHdlr *selfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000196 exitChannel chan int
197 lockDevice sync.RWMutex
198 pOnuIndication *oop.OnuIndication
199 deviceReason uint8
200 mutexDeviceReason sync.RWMutex
201 pLockStateFsm *lockStateFsm
202 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000203
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000204 //flowMgr *OpenOltFlowMgr
205 //eventMgr *OpenOltEventMgr
206 //resourceMgr *rsrcMgr.OpenOltResourceMgr
207
208 //discOnus sync.Map
209 //onus sync.Map
210 //portStats *OpenOltStatisticsMgr
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000211 collectorIsRunning bool
212 mutexCollectorFlag sync.RWMutex
213 stopCollector chan bool
214 alarmManagerIsRunning bool
215 mutextAlarmManagerFlag sync.RWMutex
216 stopAlarmManager chan bool
217 stopHeartbeatCheck chan bool
218 uniEntityMap map[uint32]*onuUniPort
219 mutexKvStoreContext sync.Mutex
220 lockVlanConfig sync.RWMutex
221 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
222 lockUpgradeFsm sync.RWMutex
223 pOnuUpradeFsm *OnuUpgradeFsm
224 reconciling uint8
225 mutexReconcilingFlag sync.RWMutex
226 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000227 reconcilingFlows bool
228 mutexReconcilingFlowsFlag sync.RWMutex
229 chReconcilingFlowsFinished chan bool //channel to indicate that reconciling of flows has been finished
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000230 mutexReadyForOmciConfig sync.RWMutex
231 readyForOmciConfig bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000232 deletionInProgress bool
233 mutexDeletionInProgressFlag sync.RWMutex
mpagenko38662d02021-08-11 09:45:19 +0000234 pLastUpgradeImageState *voltha.ImageState
235 upgradeFsmChan chan struct{}
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000236}
237
Himani Chawla6d2ae152020-09-02 13:11:20 +0530238//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530239func 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 +0530240 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000241 dh.coreProxy = cp
242 dh.AdapterProxy = ap
243 dh.EventProxy = ep
244 cloned := (proto.Clone(device)).(*voltha.Device)
245 dh.deviceID = cloned.Id
246 dh.DeviceType = cloned.Type
247 dh.adminState = "up"
248 dh.device = cloned
249 dh.pOpenOnuAc = adapter
250 dh.exitChannel = make(chan int, 1)
251 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000252 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000253 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000254 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530255 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530256 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000257 dh.stopHeartbeatCheck = make(chan bool, 2)
258 //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 +0000259 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530260 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000261 dh.lockVlanConfig = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000262 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000263 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000264 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000265 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000266 dh.reconcilingFlows = false
267 dh.chReconcilingFlowsFinished = make(chan bool)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000268 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000269 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000270 dh.pLastUpgradeImageState = &voltha.ImageState{
271 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
272 Reason: voltha.ImageState_UNKNOWN_ERROR,
273 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
274 }
275 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000276
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800277 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
278 dh.pmConfigs = cloned.PmConfigs
279 } /* else {
280 // will be populated when onu_metrics_mananger is initialized.
281 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800282
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000283 // Device related state machine
284 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000285 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000287 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
288 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
289 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
290 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
291 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000292 },
293 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000294 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
295 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
296 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
297 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
298 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
299 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
300 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
301 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000302 },
303 )
mpagenkoaf801632020-07-03 10:00:42 +0000304
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000305 return &dh
306}
307
Himani Chawla6d2ae152020-09-02 13:11:20 +0530308// start save the device to the data model
309func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000310 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000311 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000312 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000313}
314
Himani Chawla4d908332020-08-31 12:30:20 +0530315/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000316// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530317func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000318 logger.Debug("stopping-device-handler")
319 dh.exitChannel <- 1
320}
Himani Chawla4d908332020-08-31 12:30:20 +0530321*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000322
323// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530324// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000325
Girish Gowdrae0140f02021-02-02 16:55:09 -0800326//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530327func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000328 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000329
dbainbri4d3a0dc2020-12-02 00:33:42 +0000330 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000331 if dh.pDeviceStateFsm.Is(devStNull) {
332 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000333 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000334 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000335 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800336 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
337 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800338 // Now, set the initial PM configuration for that device
339 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
340 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
341 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800342 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000343 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000344 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000345 }
346
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000347}
348
mpagenko057889c2021-01-21 16:51:58 +0000349func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530350 msgBody := msg.GetBody()
351 omciMsg := &ic.InterAdapterOmciMessage{}
352 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000353 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530354 "device-id": dh.deviceID, "error": err})
355 return err
356 }
357
mpagenko80622a52021-02-09 16:53:23 +0000358 /* 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 +0530359 //assuming omci message content is hex coded!
360 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000361 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530362 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000363 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000364 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530365 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000366 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000367 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000368 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000369 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 +0530370 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000371 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000372 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530373}
374
Himani Chawla6d2ae152020-09-02 13:11:20 +0530375func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000376 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530377 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000378
dbainbri4d3a0dc2020-12-02 00:33:42 +0000379 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000380
dbainbri4d3a0dc2020-12-02 00:33:42 +0000381 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000382 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000383 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000384 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
385 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530386 if dh.pOnuTP == nil {
387 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000388 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530389 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000390 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530391 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000392 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000393 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000394 "device-state": dh.getDeviceReasonString()})
395 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530396 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000397 //previous state test here was just this one, now extended for more states to reject the SetRequest:
398 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
399 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530400
401 msgBody := msg.GetBody()
402 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
403 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000404 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530405 "device-id": dh.deviceID, "error": err})
406 return err
407 }
408
409 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000410 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
411 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530412 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000413 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000414
415 if techProfMsg.UniId > 255 {
416 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
417 techProfMsg.UniId, dh.deviceID))
418 }
419 uniID := uint8(techProfMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700420 tpID, err := GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800421 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700422 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800423 return err
424 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700425 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000426
Girish Gowdra50e56422021-06-01 16:46:04 -0700427 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530428
Girish Gowdra50e56422021-06-01 16:46:04 -0700429 switch tpInst := techProfMsg.TechTpInstance.(type) {
430 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance:
431 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
432 // if there has been some change for some uni TechProfilePath
433 //in order to allow concurrent calls to other dh instances we do not wait for execution here
434 //but doing so we can not indicate problems to the caller (who does what with that then?)
435 //by now we just assume straightforward successful execution
436 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
437 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530438
Girish Gowdra50e56422021-06-01 16:46:04 -0700439 // deadline context to ensure completion of background routines waited for
440 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
441 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
442 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000443
Girish Gowdra50e56422021-06-01 16:46:04 -0700444 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
445
446 var wg sync.WaitGroup
447 wg.Add(1) // for the 1 go routine to finish
448 // attention: deadline completion check and wg.Done is to be done in both routines
449 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
450 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
451 if tpErr := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
452 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.deviceID, "err": tpErr, "tp-path": techProfMsg.TpInstancePath})
453 return tpErr
454 }
455 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
456 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
457 pDevEntry.resetKvProcessingErrorIndication()
458 wg.Add(1) // for the 1 go routine to finish
459 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
460 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
461 if kvErr := pDevEntry.getKvProcessingErrorIndication(); kvErr != nil {
462 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.deviceID, "err": kvErr, "tp-path": techProfMsg.TpInstancePath})
463 return kvErr
464 }
465 return nil
466 default:
467 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"tp-path": techProfMsg.TpInstancePath})
468 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700469 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530470 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000471 // no change, nothing really to do - return success
Girish Gowdra50e56422021-06-01 16:46:04 -0700472 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 +0530473 return nil
474}
475
Himani Chawla6d2ae152020-09-02 13:11:20 +0530476func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000477 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530478 msg *ic.InterAdapterMessage) error {
479
480 if dh.pOnuTP == nil {
481 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000482 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530483 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000484 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530485 }
486
487 msgBody := msg.GetBody()
488 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
489 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000490 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530491 "device-id": dh.deviceID, "error": err})
492 return err
493 }
494
495 //compare TECH_PROFILE_DOWNLOAD_REQUEST
496 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000497 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530498
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000499 if delGemPortMsg.UniId > 255 {
500 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
501 delGemPortMsg.UniId, dh.deviceID))
502 }
503 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700504 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800505 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700506 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 -0800507 return err
508 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700509 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 +0000510 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000511
Mahir Gunyel9545be22021-07-04 15:53:16 -0700512 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
513 cResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000514
Himani Chawla26e555c2020-08-31 12:30:20 +0530515}
516
Himani Chawla6d2ae152020-09-02 13:11:20 +0530517func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000518 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530519 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000520
dbainbri4d3a0dc2020-12-02 00:33:42 +0000521 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000522 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000523 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000524 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
525 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530526 if dh.pOnuTP == nil {
527 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000528 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530529 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000530 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530531 }
532
533 msgBody := msg.GetBody()
534 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
535 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000536 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530537 "device-id": dh.deviceID, "error": err})
538 return err
539 }
540
541 //compare TECH_PROFILE_DOWNLOAD_REQUEST
542 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000543 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000544
545 if delTcontMsg.UniId > 255 {
546 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
547 delTcontMsg.UniId, dh.deviceID))
548 }
549 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700550 tpPath := delTcontMsg.TpInstancePath
Girish Gowdra041dcb32020-11-16 16:54:30 -0800551 tpID, err := GetTpIDFromTpPath(tpPath)
552 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000553 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800554 return err
555 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700556 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 +0000557
Mahir Gunyel9545be22021-07-04 15:53:16 -0700558 pDevEntry.freeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530559
Mahir Gunyel9545be22021-07-04 15:53:16 -0700560 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
561 cResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000562
Mahir Gunyel9545be22021-07-04 15:53:16 -0700563}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000564
Mahir Gunyel9545be22021-07-04 15:53:16 -0700565func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
566 uniID uint8, tpID uint8, pathString string, resource resourceEntry, entryID uint32) error {
567 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
568 if pDevEntry == nil {
569 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
570 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530571 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700572 var resourceName string
573 if cResourceGemPort == resource {
574 resourceName = "Gem"
575 } else {
576 resourceName = "Tcont"
577 }
578
579 // deadline context to ensure completion of background routines waited for
580 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
581 dctx, cancel := context.WithDeadline(context.Background(), deadline)
582
583 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
584
585 var wg sync.WaitGroup
586 wg.Add(1) // for the 1 go routine to finish
587 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
588 resource, entryID, &wg)
589 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
590 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); err != nil {
591 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
592 return err
593 }
594
595 if dh.pOnuTP.isTechProfileConfigCleared(ctx, uniID, tpID) {
596 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID})
597 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
598 pDevEntry.resetKvProcessingErrorIndication()
599 var wg2 sync.WaitGroup
600 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
601 wg2.Add(1)
602 // Removal of the gem id mapping represents the removal of the tech profile
603 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID})
604 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
605 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
606 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
607 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
608 return err
609 }
610 }
611 }
612 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.deviceID,
613 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530614 return nil
615}
616
Himani Chawla6d2ae152020-09-02 13:11:20 +0530617//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000618// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
619// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000620func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000621 msgID := msg.Header.Id
622 msgType := msg.Header.Type
623 fromTopic := msg.Header.FromTopic
624 toTopic := msg.Header.ToTopic
625 toDeviceID := msg.Header.ToDeviceId
626 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000627 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000628 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
629
630 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000631 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000632 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
633 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000634 {
mpagenko057889c2021-01-21 16:51:58 +0000635 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000636 }
mpagenkoaf801632020-07-03 10:00:42 +0000637 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
638 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000639 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000640 }
641 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
642 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000643 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000644
mpagenkoaf801632020-07-03 10:00:42 +0000645 }
646 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
647 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000648 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000649 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000650 default:
651 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000652 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000653 "msgType": msg.Header.Type, "device-id": dh.deviceID})
654 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000655 }
656 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000657}
658
mpagenkodff5dda2020-08-28 11:52:01 +0000659//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000660func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
661 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000662 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
ozgecanetsia82b91a62021-05-21 18:54:49 +0300663 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID, "metadata": apFlowMetaData})
mpagenko01e726e2020-10-23 09:45:29 +0000664 var retError error = nil
665 //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 +0000666 if apOfFlowChanges.ToRemove != nil {
667 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000668 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000669 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000670 "device-id": dh.deviceID})
671 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000672 continue
673 }
674 flowInPort := flow.GetInPort(flowItem)
675 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000676 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 +0000677 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
678 continue
679 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000680 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000681 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000682 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000683 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000684 continue
685 } else {
686 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530687 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000688 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
689 loUniPort = uniPort
690 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000691 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000692 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
693 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
694 flowInPort, dh.deviceID)
695 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000696 }
697 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000698 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000699 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000700 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000701 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000702 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000703 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000704 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000705 log.Fields{"device-id": dh.deviceID, "error": err})
706 retError = err
707 continue
708 //return err
709 } else { // if last setting succeeds, overwrite possibly previously set error
710 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000711 }
712 }
713 }
714 }
mpagenko01e726e2020-10-23 09:45:29 +0000715 if apOfFlowChanges.ToAdd != nil {
716 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
717 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000718 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000719 "device-id": dh.deviceID})
720 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
721 continue
722 }
723 flowInPort := flow.GetInPort(flowItem)
724 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000725 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 +0000726 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
727 continue
728 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
729 } else if flowInPort == dh.ponPortNumber {
730 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000731 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000732 "device-id": dh.deviceID, "inPort": flowInPort})
733 continue
734 } else {
735 // this is the relevant upstream flow
736 var loUniPort *onuUniPort
737 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
738 loUniPort = uniPort
739 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000740 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000741 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
742 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
743 flowInPort, dh.deviceID)
744 continue
745 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
746 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000747 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
748 // if not, we just throw some error here to have an indication about that, if we really need to support that
749 // then we would need to create some means to activate the internal stored flows
750 // after the device gets active automatically (and still with its dependency to the TechProfile)
751 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
752 // also abort for the other still possible flows here
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000753 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000754 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000755 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000756 return fmt.Errorf("improper device state on device %s", dh.deviceID)
757 }
758
mpagenko01e726e2020-10-23 09:45:29 +0000759 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000760 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000761 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
762 "uniPortName": loUniPort.name})
ozgecanetsia82b91a62021-05-21 18:54:49 +0300763 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort, apFlowMetaData)
mpagenko01e726e2020-10-23 09:45:29 +0000764 //try next flow after processing error
765 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000766 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000767 log.Fields{"device-id": dh.deviceID, "error": err})
768 retError = err
769 continue
770 //return err
771 } else { // if last setting succeeds, overwrite possibly previously set error
772 retError = nil
773 }
774 }
775 }
776 }
777 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000778}
779
Himani Chawla6d2ae152020-09-02 13:11:20 +0530780//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000781//following are the expected device states after this activity:
782//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
783// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000784func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
785 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000786
mpagenko900ee4b2020-10-12 11:56:34 +0000787 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000788 //note that disableDevice sequences in some 'ONU active' state may yield also
789 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000790 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000791 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000792 //disable-device shall be just a UNi/ONU-G related admin state setting
793 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000794
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000795 if dh.isReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000796 // disable UNI ports/ONU
797 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
798 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000799 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000800 } else { //LockStateFSM already init
801 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000802 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000803 }
804 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000805 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000806 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000807 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000808 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
809 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000810 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000811 }
mpagenko01e726e2020-10-23 09:45:29 +0000812 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000813
814 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000815 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000816 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300817 }
818}
819
Himani Chawla6d2ae152020-09-02 13:11:20 +0530820//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000821func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
822 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000823
mpagenkoaa3afe92021-05-21 16:20:58 +0000824 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000825 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
826 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
827 // for real ONU's that should have nearly no influence
828 // Note that for real ONU's there is anyway a problematic situation with following sequence:
829 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
830 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
831 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000832 dh.setReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000833
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000834 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000835 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000836 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000837 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000838 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000839 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000840 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000841 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300842}
843
dbainbri4d3a0dc2020-12-02 00:33:42 +0000844func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
845 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000846
dbainbri4d3a0dc2020-12-02 00:33:42 +0000847 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000848 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000849 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000850 return
851 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000852 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000853 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000854 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000855 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000856 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000857 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700858 dh.stopReconciling(ctx, false)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000859 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000860 }
Himani Chawla4d908332020-08-31 12:30:20 +0530861 var onuIndication oop.OnuIndication
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000862 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000863 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
864 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
865 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
866 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000867 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000868 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000869}
870
dbainbri4d3a0dc2020-12-02 00:33:42 +0000871func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
872 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000873
dbainbri4d3a0dc2020-12-02 00:33:42 +0000874 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000875 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000876 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000877 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700878 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000879 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000880 return
881 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000882 dh.pOnuTP.lockTpProcMutex()
883 defer dh.pOnuTP.unlockTpProcMutex()
884
mpagenko2dc896e2021-08-02 12:03:59 +0000885 pDevEntry.mutexPersOnuConfig.RLock()
886 persMutexLock := true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000887 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko2dc896e2021-08-02 12:03:59 +0000888 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000889 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000890 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000891 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700892 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000893 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000894 return
895 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000896 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700897 techProfsFound := false
898 techProfInstLoadFailed := false
899outerLoop:
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000900 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000901 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
902 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000903 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000904 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000905 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000906 }
mpagenko2dc896e2021-08-02 12:03:59 +0000907 //release mutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
908 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
909 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
910 pDevEntry.mutexPersOnuConfig.RUnlock()
911 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700912 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800913 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700914 // Request the TpInstance again from the openolt adapter in case of reconcile
915 iaTechTpInst, err := dh.AdapterProxy.TechProfileInstanceRequest(ctx, uniData.PersTpPathMap[tpID],
916 dh.device.ParentPortNo, dh.device.ProxyAddress.OnuId, uint32(uniData.PersUniID),
917 dh.pOpenOnuAc.config.Topic, dh.ProxyAddressType,
918 dh.parentID, dh.ProxyAddressID)
919 if err != nil || iaTechTpInst == nil {
920 logger.Errorw(ctx, "error fetching tp instance",
921 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID, "err": err})
922 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
923 break outerLoop
924 }
925 var tpInst tech_profile.TechProfileInstance
926 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
927 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
928 tpInst = *techTpInst.TpInstance
mpagenko2dc896e2021-08-02 12:03:59 +0000929 logger.Debugw(ctx, "received-tp-instance-successfully-after-reconcile", log.Fields{
930 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700931 default: // do not support epon or other tech
mpagenko2dc896e2021-08-02 12:03:59 +0000932 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
933 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700934 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
935 break outerLoop
936 }
937
Girish Gowdra041dcb32020-11-16 16:54:30 -0800938 // deadline context to ensure completion of background routines waited for
939 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
940 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000941 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000942
Girish Gowdra041dcb32020-11-16 16:54:30 -0800943 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
944 var wg sync.WaitGroup
945 wg.Add(1) // for the 1 go routine to finish
Girish Gowdra50e56422021-06-01 16:46:04 -0700946 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000947 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800948 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000949 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700950 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
951 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800952 }
mpagenko2dc896e2021-08-02 12:03:59 +0000953 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000954 if len(uniData.PersFlowParams) != 0 {
955 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000956 }
mpagenko2dc896e2021-08-02 12:03:59 +0000957 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
958 persMutexLock = true
959 } // for all UNI entries from sOnuPersistentData
960 if persMutexLock { // if loop was left with mutexPersOnuConfig still set
961 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000962 }
mpagenko2dc896e2021-08-02 12:03:59 +0000963
964 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
965 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
966}
967
968func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
969 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
970 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000971 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
972 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000973 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700974 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000975 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000976 return
977 }
mpagenko2dc896e2021-08-02 12:03:59 +0000978 if abTechProfInstLoadFailed {
Girish Gowdra50e56422021-06-01 16:46:04 -0700979 dh.setDeviceReason(drTechProfileConfigDownloadFailed)
980 dh.stopReconciling(ctx, false)
981 return
982 } else if dh.isSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000983 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
984 }
mpagenko2dc896e2021-08-02 12:03:59 +0000985 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000986 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
987 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000988 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700989 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000990 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000991 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000992}
993
dbainbri4d3a0dc2020-12-02 00:33:42 +0000994func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
995 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000996
dbainbri4d3a0dc2020-12-02 00:33:42 +0000997 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000998 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000999 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001000 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001001 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001002 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001003 return
1004 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001005
mpagenko2dc896e2021-08-02 12:03:59 +00001006 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001007 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko2dc896e2021-08-02 12:03:59 +00001008 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001009 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001010 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001011 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001012 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001013 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001014 return
1015 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001016 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001017 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001018 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1019 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001020 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001021 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001022 continue
1023 }
1024 if len(uniData.PersTpPathMap) == 0 {
1025 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
1026 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001027 // It doesn't make sense to configure any flows if no TPs are available
1028 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001029 }
mpagenko2dc896e2021-08-02 12:03:59 +00001030 //release mutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1031 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
1032 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1033 pDevEntry.mutexPersOnuConfig.RUnlock()
1034
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001035 var uniPort *onuUniPort
1036 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +00001037 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001038 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001039 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
1040 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001041 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001042 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001043 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001044 return
1045 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001046 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001047 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001048 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001049 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001050 for _, flowData := range uniData.PersFlowParams {
mpagenko2dc896e2021-08-02 12:03:59 +00001051 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1052 "device-id": dh.deviceID, "uni-id": uniData.PersUniID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001053 // If this is the last flow for the device we need to announce it the waiting
1054 // chReconcilingFlowsFinished channel
1055 if flowsProcessed == len(uniData.PersFlowParams)-1 {
1056 lastFlowToReconcile = true
1057 }
mpagenko01e726e2020-10-23 09:45:29 +00001058 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenko7d14de12021-07-27 08:31:56 +00001059 dh.lockVlanConfig.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001060 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001061 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +00001062 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +03001063 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001064 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001065 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001066 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001067 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00001068 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +03001069 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001070 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001071 }
1072 }
mpagenko7d14de12021-07-27 08:31:56 +00001073 dh.lockVlanConfig.Unlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001074 flowsProcessed++
mpagenko2dc896e2021-08-02 12:03:59 +00001075 } //for all flows of this UNI
1076 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
1077 "device-id": dh.deviceID, "uni-id": uniData.PersUniID, "flowsProcessed": flowsProcessed,
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001078 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
1079 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001080 // this can't be used as global finished reconciling flag because
1081 // assumes is getting called before the state machines for the last flow is completed,
1082 // while this is not guaranteed.
1083 //dh.setReconcilingFlows(false)
mpagenko2dc896e2021-08-02 12:03:59 +00001084 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
1085 } // for all UNI entries from sOnuPersistentData
1086 pDevEntry.mutexPersOnuConfig.RUnlock()
1087
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001088 if !flowsFound {
1089 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
1090 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001091 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001092 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001093 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001094 return
1095 }
1096 if dh.isSkipOnuConfigReconciling() {
1097 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001098 }
1099}
1100
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001101func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
1102 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001103 dh.stopReconciling(ctx, true)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001104}
1105
dbainbri4d3a0dc2020-12-02 00:33:42 +00001106func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
1107 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001108
dbainbri4d3a0dc2020-12-02 00:33:42 +00001109 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001110 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001111 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +00001112 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001113 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001114 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001115
1116 // deadline context to ensure completion of background routines waited for
1117 //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 +05301118 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001119 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001120
1121 pDevEntry.resetKvProcessingErrorIndication()
1122
1123 var wg sync.WaitGroup
1124 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001125 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1126 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001127
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001128 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001129 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001130}
1131
mpagenko15ff4a52021-03-02 10:09:20 +00001132//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1133// before this change here return like this was used:
1134// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1135//was and is called in background - error return does not make sense
1136func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1137 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1138 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001139 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001140 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001141 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001142 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301143 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001144 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001145 return
Himani Chawla4d908332020-08-31 12:30:20 +05301146 }
mpagenko01e726e2020-10-23 09:45:29 +00001147
1148 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001149 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001150
dbainbri4d3a0dc2020-12-02 00:33:42 +00001151 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001152 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001153 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001154 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001155 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001156 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001157 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001158 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001159 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001160 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001161 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001162 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001163 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1164 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1165 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1166 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001167}
1168
mpagenkoc8bba412021-01-15 15:38:44 +00001169//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001170// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001171func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1172 apDownloadManager *adapterDownloadManager) error {
1173 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001174 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001175
1176 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001177 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1178 if pDevEntry == nil {
1179 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1180 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1181 }
1182
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001183 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001184 var inactiveImageID uint16
1185 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1186 dh.lockUpgradeFsm.Lock()
1187 defer dh.lockUpgradeFsm.Unlock()
1188 if dh.pOnuUpradeFsm == nil {
1189 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1190 if err == nil {
1191 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1192 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1193 "device-id": dh.deviceID, "error": err})
1194 }
1195 } else {
1196 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001197 "device-id": dh.deviceID, "error": err})
1198 }
mpagenko15ff4a52021-03-02 10:09:20 +00001199 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1200 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
mpagenko38662d02021-08-11 09:45:19 +00001201 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1202 //no effort spent anymore for the old API to automatically cancel and restart the download
1203 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001204 }
mpagenko15ff4a52021-03-02 10:09:20 +00001205 } else {
1206 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1207 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001208 }
1209 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001210 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1211 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001212 }
1213 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001214}
1215
mpagenkoc26d4c02021-05-06 14:27:57 +00001216//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1217// after the OnuImage has been downloaded to the adapter, called in background
1218func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
1219 apDownloadManager *fileDownloadManager, aImageIdentifier string) {
1220
1221 var err error
1222 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1223 if pDevEntry == nil {
1224 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1225 return
1226 }
1227
1228 var inactiveImageID uint16
1229 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1230 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
1231 "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001232
1233 dh.lockUpgradeFsm.RLock()
1234 lopOnuUpradeFsm := dh.pOnuUpradeFsm
1235 //lockUpgradeFsm must be release before cancellation as this may implicitly request removeOnuUpgradeFsm()
1236 dh.lockUpgradeFsm.RUnlock()
1237 if lopOnuUpradeFsm != nil {
1238 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1239 // abort the current processing, running upgrades are always aborted by newer request
1240 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.deviceID})
1241 //flush the remove upgradeFsmChan channel
1242 select {
1243 case <-dh.upgradeFsmChan:
1244 logger.Debug(ctx, "flushed-upgrade-fsm-channel")
1245 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001246 }
mpagenko38662d02021-08-11 09:45:19 +00001247 lopOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1248 select {
1249 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
1250 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.deviceID})
1251 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1252 return
1253 case <-dh.upgradeFsmChan:
1254 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.deviceID})
1255 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001256 }
mpagenko38662d02021-08-11 09:45:19 +00001257
1258 //here it can be assumed that no running upgrade processing exists (anymore)
1259 //OmciOnuSwUpgradeDone could be used to create some Kafka event with information on upgrade completion,
1260 // but none yet defined
1261 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1262 if err == nil {
1263 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1264 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1265 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
mpagenkoc26d4c02021-05-06 14:27:57 +00001266 "device-id": dh.deviceID, "error": err})
1267 return
1268 }
mpagenko38662d02021-08-11 09:45:19 +00001269 } else {
1270 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1271 "device-id": dh.deviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001272 }
1273 return
1274 }
1275 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1276 "device-id": dh.deviceID, "error": err})
1277}
1278
1279//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001280func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1281 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001282 var err error
1283 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1284 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1285 // 2.) activation of the inactive image
1286
1287 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1288 if pDevEntry == nil {
1289 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001290 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001291 }
1292 dh.lockUpgradeFsm.RLock()
1293 if dh.pOnuUpradeFsm != nil {
1294 dh.lockUpgradeFsm.RUnlock()
1295 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1296 dh.deviceID, dh.deviceID)
1297 if getErr != nil || onuVolthaDevice == nil {
1298 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 +00001299 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001300 }
1301 // use the OnuVendor identification from this device for the internal unique name
1302 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001303 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001304 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001305 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001306 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1307 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001308 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001309 }
mpagenko183647c2021-06-08 15:25:04 +00001310 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1311 "device-id": dh.deviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001312 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001313 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001314 } //else
1315 dh.lockUpgradeFsm.RUnlock()
1316
1317 // 2.) check if requested image-version equals the inactive one and start its activation
1318 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1319 var inactiveImageID uint16
1320 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1321 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1322 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
mpagenko183647c2021-06-08 15:25:04 +00001323 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001324 }
1325 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1326 if err == nil {
1327 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1328 inactiveImageID, aCommitRequest); err != nil {
1329 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1330 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001331 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001332 }
1333 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1334 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001335 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001336 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001337 } //else
1338 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1339 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001340 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001341}
1342
1343//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001344func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1345 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001346 var err error
1347 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1348 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1349 // 2.) commitment of the active image
1350
1351 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1352 if pDevEntry == nil {
1353 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001354 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001355 }
1356 dh.lockUpgradeFsm.RLock()
1357 if dh.pOnuUpradeFsm != nil {
1358 dh.lockUpgradeFsm.RUnlock()
1359 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1360 dh.deviceID, dh.deviceID)
1361 if getErr != nil || onuVolthaDevice == nil {
1362 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 +00001363 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001364 }
1365 // use the OnuVendor identification from this device for the internal unique name
1366 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001367 // 1.) check a started upgrade process and relay the commitment request to it
1368 // the running upgrade may be based either on the imageIdentifier (started from download)
1369 // or on the imageVersion (started from pure activation)
1370 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1371 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001372 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1373 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001374 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001375 }
mpagenko183647c2021-06-08 15:25:04 +00001376 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1377 "device-id": dh.deviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001378 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001379 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001380 } //else
1381 dh.lockUpgradeFsm.RUnlock()
1382
mpagenko183647c2021-06-08 15:25:04 +00001383 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001384 var activeImageID uint16
1385 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1386 logger.Errorw(ctx, "get active image failed", log.Fields{
1387 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
mpagenko183647c2021-06-08 15:25:04 +00001388 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001389 }
1390 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1391 if err == nil {
1392 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1393 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1394 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001395 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001396 }
1397 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1398 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001399 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001400 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001401 } //else
1402 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1403 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001404 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001405}
1406
mpagenkoaa3afe92021-05-21 16:20:58 +00001407func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001408 aVersion string) *voltha.ImageState {
1409 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001410 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001411 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001412 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001413 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1414 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1415 if aVersion == dh.pLastUpgradeImageState.Version {
1416 pImageState = dh.pLastUpgradeImageState
1417 } else { //state request for an image version different from last processed image version
1418 pImageState = &voltha.ImageState{
1419 Version: aVersion,
1420 //we cannot state something concerning this version
1421 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1422 Reason: voltha.ImageState_NO_ERROR,
1423 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1424 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001425 }
1426 }
mpagenko38662d02021-08-11 09:45:19 +00001427 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001428}
1429
1430func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1431 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1432 pDeviceImageState.DeviceId = dh.deviceID
mpagenko7455fd42021-06-10 16:25:55 +00001433 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001434 dh.lockUpgradeFsm.RLock()
1435 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001436 if aVersion == dh.pOnuUpradeFsm.GetImageVersion(ctx) {
1437 // so then we cancel the upgrade operation
1438 // but before we still request the actual ImageState (which should not change with the cancellation)
1439 pDeviceImageState.ImageState.ImageState = dh.pOnuUpradeFsm.GetSpecificImageState(ctx)
1440 dh.lockUpgradeFsm.RUnlock()
1441 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
1442 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1443 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1444 } else { //nothing to cancel, states unknown
1445 dh.lockUpgradeFsm.RUnlock()
1446 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1447 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1448 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1449 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001450 } else {
mpagenko38662d02021-08-11 09:45:19 +00001451 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1452 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1453 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1454 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1455 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1456 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001457 dh.lockUpgradeFsm.RUnlock()
1458 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1459 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001460 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1461 //an abort request to a not active upgrade processing can be used to reset the device upgrade states completely
mpagenkoaa3afe92021-05-21 16:20:58 +00001462 }
1463}
1464
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001465func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1466
1467 var onuImageStatus *OnuImageStatus
1468
1469 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1470 if pDevEntry != nil {
1471 onuImageStatus = NewOnuImageStatus(pDevEntry)
1472 pDevEntry.mutexOnuImageStatus.Lock()
1473 pDevEntry.pOnuImageStatus = onuImageStatus
1474 pDevEntry.mutexOnuImageStatus.Unlock()
1475
1476 } else {
1477 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1478 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1479 }
1480 images, err := onuImageStatus.getOnuImageStatus(ctx)
1481 pDevEntry.mutexOnuImageStatus.Lock()
1482 pDevEntry.pOnuImageStatus = nil
1483 pDevEntry.mutexOnuImageStatus.Unlock()
1484 return images, err
1485}
1486
Himani Chawla6d2ae152020-09-02 13:11:20 +05301487// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001488// #####################################################################################
1489
1490// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301491// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001492
dbainbri4d3a0dc2020-12-02 00:33:42 +00001493func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1494 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 +00001495}
1496
1497// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001498func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001499
dbainbri4d3a0dc2020-12-02 00:33:42 +00001500 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001501 var err error
1502
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001503 // populate what we know. rest comes later after mib sync
1504 dh.device.Root = false
1505 dh.device.Vendor = "OpenONU"
1506 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001507 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001508 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001509
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001510 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001511
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001512 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001513 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1514 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301515 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001516 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001517 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001518 log.Fields{"device-id": dh.deviceID})
1519 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001520
Himani Chawla4d908332020-08-31 12:30:20 +05301521 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001522 dh.ponPortNumber = dh.device.ParentPortNo
1523
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001524 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1525 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1526 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001527 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001528 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301529 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001530
1531 /*
1532 self._pon = PonPort.create(self, self._pon_port_number)
1533 self._pon.add_peer(self.parent_id, self._pon_port_number)
1534 self.logger.debug('adding-pon-port-to-agent',
1535 type=self._pon.get_port().type,
1536 admin_state=self._pon.get_port().admin_state,
1537 oper_status=self._pon.get_port().oper_status,
1538 )
1539 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001540 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001541 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001542 var ponPortNo uint32 = 1
1543 if dh.ponPortNumber != 0 {
1544 ponPortNo = dh.ponPortNumber
1545 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001546
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001547 pPonPort := &voltha.Port{
1548 PortNo: ponPortNo,
1549 Label: fmt.Sprintf("pon-%d", ponPortNo),
1550 Type: voltha.Port_PON_ONU,
1551 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301552 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001553 PortNo: ponPortNo}}, // Peer port is parent's port number
1554 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001555 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1556 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001557 e.Cancel(err)
1558 return
1559 }
1560 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001561 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001562 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001563 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001564}
1565
1566// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001567func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001568
dbainbri4d3a0dc2020-12-02 00:33:42 +00001569 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001570 var err error
1571 /*
1572 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1573 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1574 return nil
1575 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001576 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1577 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001578 e.Cancel(err)
1579 return
1580 }
1581
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001582 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001583 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001584 // reconcilement will be continued after mib download is done
1585 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001586
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001587 /*
1588 ############################################################################
1589 # Setup Alarm handler
1590 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1591 device.serial_number)
1592 ############################################################################
1593 # Setup PM configuration for this device
1594 # Pass in ONU specific options
1595 kwargs = {
1596 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1597 'heartbeat': self.heartbeat,
1598 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1599 }
1600 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1601 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1602 self.logical_device_id, device.serial_number,
1603 grouped=True, freq_override=False, **kwargs)
1604 pm_config = self._pm_metrics.make_proto()
1605 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1606 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1607 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1608
1609 # Note, ONU ID and UNI intf set in add_uni_port method
1610 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1611 ani_ports=[self._pon])
1612
1613 # Code to Run OMCI Test Action
1614 kwargs_omci_test_action = {
1615 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1616 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1617 }
1618 serial_number = device.serial_number
1619 self._test_request = OmciTestRequest(self.core_proxy,
1620 self.omci_agent, self.device_id,
1621 AniG, serial_number,
1622 self.logical_device_id,
1623 exclusive=False,
1624 **kwargs_omci_test_action)
1625
1626 self.enabled = True
1627 else:
1628 self.logger.info('onu-already-activated')
1629 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001630
dbainbri4d3a0dc2020-12-02 00:33:42 +00001631 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001632}
1633
1634// doStateConnected get the device info and update to voltha core
1635// for comparison of the original method (not that easy to uncomment): compare here:
1636// voltha-openolt-adapter/adaptercore/device_handler.go
1637// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001638func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001639
dbainbri4d3a0dc2020-12-02 00:33:42 +00001640 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301641 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001642 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001643 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001644}
1645
1646// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001648
dbainbri4d3a0dc2020-12-02 00:33:42 +00001649 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301650 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001651 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001652 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001653
1654 /*
1655 // Synchronous call to update device state - this method is run in its own go routine
1656 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1657 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001658 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 +00001659 return err
1660 }
1661 return nil
1662 */
1663}
1664
1665// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001666func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001667
dbainbri4d3a0dc2020-12-02 00:33:42 +00001668 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001669 var err error
1670
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001671 device := dh.device
1672 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001673 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001674 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001675 e.Cancel(err)
1676 return
1677 }
1678
1679 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001680 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001681 /*
1682 // Update the all ports state on that device to disable
1683 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001684 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001685 return er
1686 }
1687
1688 //Update the device oper state and connection status
1689 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1690 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1691 dh.device = cloned
1692
1693 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001694 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001695 return er
1696 }
1697
1698 //get the child device for the parent device
1699 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1700 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001701 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001702 return err
1703 }
1704 for _, onuDevice := range onuDevices.Items {
1705
1706 // Update onu state as down in onu adapter
1707 onuInd := oop.OnuIndication{}
1708 onuInd.OperState = "down"
1709 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1710 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1711 if er != nil {
1712 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001713 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001714 //Do not return here and continue to process other ONUs
1715 }
1716 }
1717 // * Discovered ONUs entries need to be cleared , since after OLT
1718 // is up, it starts sending discovery indications again* /
1719 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001720 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001721 return nil
1722 */
Himani Chawla4d908332020-08-31 12:30:20 +05301723 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001724 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001725 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001726}
1727
Himani Chawla6d2ae152020-09-02 13:11:20 +05301728// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001729// #################################################################################
1730
1731// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301732// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001733
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001734//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001735func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001736 dh.lockDevice.RLock()
1737 pOnuDeviceEntry := dh.pOnuOmciDevice
1738 if aWait && pOnuDeviceEntry == nil {
1739 //keep the read sema short to allow for subsequent write
1740 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001742 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1743 // so it might be needed to wait here for that event with some timeout
1744 select {
1745 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001746 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001747 return nil
1748 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001749 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001750 // if written now, we can return the written value without sema
1751 return dh.pOnuOmciDevice
1752 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001753 }
mpagenko3af1f032020-06-10 08:53:41 +00001754 dh.lockDevice.RUnlock()
1755 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001756}
1757
Himani Chawla6d2ae152020-09-02 13:11:20 +05301758//setOnuDeviceEntry sets the ONU device entry within the handler
1759func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001760 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001761 dh.lockDevice.Lock()
1762 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001763 dh.pOnuOmciDevice = apDeviceEntry
1764 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001765 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301766 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001767 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001768}
1769
Himani Chawla6d2ae152020-09-02 13:11:20 +05301770//addOnuDeviceEntry creates a new ONU device or returns the existing
1771func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001772 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001773
dbainbri4d3a0dc2020-12-02 00:33:42 +00001774 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001775 if deviceEntry == nil {
1776 /* costum_me_map in python code seems always to be None,
1777 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1778 /* also no 'clock' argument - usage open ...*/
1779 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001780 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001781 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001782 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301783 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001784 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001785 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001786 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001787 // fire deviceEntry ready event to spread to possibly waiting processing
1788 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001789 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001790 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001791 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001792 }
1793 // might be updated with some error handling !!!
1794 return nil
1795}
1796
dbainbri4d3a0dc2020-12-02 00:33:42 +00001797func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1798 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001799 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1800
1801 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001802
dbainbri4d3a0dc2020-12-02 00:33:42 +00001803 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001804 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001805 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001806 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1807 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001808 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001809 if err := dh.storePersistentData(ctx); err != nil {
1810 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001811 log.Fields{"device-id": dh.deviceID, "err": err})
1812 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001813 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001814 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001815 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001816 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1817 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001818 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001819 }
1820 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001821 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001822 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001823
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001824 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001825 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001826 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001827 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 +00001828 log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001829 dh.stopReconciling(ctx, true)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001830 } else {
1831 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001832 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001833 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001834 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1835 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1836 // 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 +00001837 // 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 +00001838 // so let's just try to keep it simple ...
1839 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001840 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001841 if err != nil || device == nil {
1842 //TODO: needs to handle error scenarios
1843 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1844 return errors.New("Voltha Device not found")
1845 }
1846 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001847
dbainbri4d3a0dc2020-12-02 00:33:42 +00001848 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001849 return err
mpagenko3af1f032020-06-10 08:53:41 +00001850 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001851
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001852 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001853
1854 /* this might be a good time for Omci Verify message? */
1855 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001856 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001857 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001858 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001859 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001860
1861 /* give the handler some time here to wait for the OMCi verification result
1862 after Timeout start and try MibUpload FSM anyway
1863 (to prevent stopping on just not supported OMCI verification from ONU) */
1864 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001865 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001866 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001867 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001868 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001869 }
1870
1871 /* In py code it looks earlier (on activate ..)
1872 # Code to Run OMCI Test Action
1873 kwargs_omci_test_action = {
1874 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1875 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1876 }
1877 serial_number = device.serial_number
1878 self._test_request = OmciTestRequest(self.core_proxy,
1879 self.omci_agent, self.device_id,
1880 AniG, serial_number,
1881 self.logical_device_id,
1882 exclusive=False,
1883 **kwargs_omci_test_action)
1884 ...
1885 # Start test requests after a brief pause
1886 if not self._test_request_started:
1887 self._test_request_started = True
1888 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1889 reactor.callLater(tststart, self._test_request.start_collector)
1890
1891 */
1892 /* which is then: in omci_test_request.py : */
1893 /*
1894 def start_collector(self, callback=None):
1895 """
1896 Start the collection loop for an adapter if the frequency > 0
1897
1898 :param callback: (callable) Function to call to collect PM data
1899 """
1900 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1901 if callback is None:
1902 callback = self.perform_test_omci
1903
1904 if self.lc is None:
1905 self.lc = LoopingCall(callback)
1906
1907 if self.default_freq > 0:
1908 self.lc.start(interval=self.default_freq / 10)
1909
1910 def perform_test_omci(self):
1911 """
1912 Perform the initial test request
1913 """
1914 ani_g_entities = self._device.configuration.ani_g_entities
1915 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1916 is not None else None
1917 self._entity_id = ani_g_entities_ids[0]
1918 self.logger.info('perform-test', entity_class=self._entity_class,
1919 entity_id=self._entity_id)
1920 try:
1921 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1922 result = yield self._device.omci_cc.send(frame)
1923 if not result.fields['omci_message'].fields['success_code']:
1924 self.logger.info('Self-Test Submitted Successfully',
1925 code=result.fields[
1926 'omci_message'].fields['success_code'])
1927 else:
1928 raise TestFailure('Test Failure: {}'.format(
1929 result.fields['omci_message'].fields['success_code']))
1930 except TimeoutError as e:
1931 self.deferred.errback(failure.Failure(e))
1932
1933 except Exception as e:
1934 self.logger.exception('perform-test-Error', e=e,
1935 class_id=self._entity_class,
1936 entity_id=self._entity_id)
1937 self.deferred.errback(failure.Failure(e))
1938
1939 */
1940
1941 // PM related heartbeat??? !!!TODO....
1942 //self._heartbeat.enabled = True
1943
mpagenko1cc3cb42020-07-27 15:24:38 +00001944 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1945 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1946 * 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 +05301947 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001948 */
1949 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001950 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001951 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001952 if pMibUlFsm.Is(ulStDisabled) {
1953 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001954 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 +00001955 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301956 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001957 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301958 //Determine ONU status and start/re-start MIB Synchronization tasks
1959 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001960 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301961 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001962 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 +00001963 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001964 }
Himani Chawla4d908332020-08-31 12:30:20 +05301965 } else {
1966 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001967 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 +00001968 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301969 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001970 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001971 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001972 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001974 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001975 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001976 }
1977 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001978 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001979 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001980 }
1981 return nil
1982}
1983
dbainbri4d3a0dc2020-12-02 00:33:42 +00001984func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001985 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001986 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001987 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001988 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001989
mpagenko900ee4b2020-10-12 11:56:34 +00001990 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1991 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1992 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001993 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001994 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001995 log.Fields{"device-id": dh.deviceID, "error": err})
1996 // abort: system behavior is just unstable ...
1997 return err
1998 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001999 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002000 _ = 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 +00002001
2002 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
2003 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
2004 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00002005 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002006 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002007 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002008 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002009 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002010 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002011
2012 //TODO!!! remove existing traffic profiles
2013 /* from py code, if TP's exist, remove them - not yet implemented
2014 self._tp = dict()
2015 # Let TP download happen again
2016 for uni_id in self._tp_service_specific_task:
2017 self._tp_service_specific_task[uni_id].clear()
2018 for uni_id in self._tech_profile_download_done:
2019 self._tech_profile_download_done[uni_id].clear()
2020 */
2021
dbainbri4d3a0dc2020-12-02 00:33:42 +00002022 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002023
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002024 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002025
dbainbri4d3a0dc2020-12-02 00:33:42 +00002026 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002027 // abort: system behavior is just unstable ...
2028 return err
2029 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002030 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002031 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002032 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00002033 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002034 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002035 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00002036 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002037 // abort: system behavior is just unstable ...
2038 return err
2039 }
2040 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002041 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002042 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002043 return nil
2044}
2045
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002046func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002047 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2048 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2049 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2050 // and using the stop/reset event should never harm
2051
dbainbri4d3a0dc2020-12-02 00:33:42 +00002052 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002053 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002054 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002055 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2056 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002057 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002058 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002059 }
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002060 pDevEntry.mutexOnuImageStatus.RLock()
2061 if pDevEntry.pOnuImageStatus != nil {
2062 pDevEntry.pOnuImageStatus.CancelProcessing(ctx)
2063 }
2064 pDevEntry.mutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002065
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002066 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002067 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002068 }
2069 //MibDownload may run
2070 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2071 if pMibDlFsm != nil {
2072 _ = pMibDlFsm.Event(dlEvReset)
2073 }
2074 //port lock/unlock FSM's may be active
2075 if dh.pUnlockStateFsm != nil {
2076 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2077 }
2078 if dh.pLockStateFsm != nil {
2079 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2080 }
2081 //techProfile related PonAniConfigFsm FSM may be active
2082 if dh.pOnuTP != nil {
2083 // should always be the case here
2084 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
2085 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08002086 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00002087 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002088 }
mpagenko900ee4b2020-10-12 11:56:34 +00002089 }
2090 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002091 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002092 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00002093 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
2094 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002095 dh.lockVlanConfig.RUnlock()
2096 //reset of all Fsm is always accompanied by global persistency data removal
2097 // no need to remove specific data
2098 pVlanFilterFsm.RequestClearPersistency(false)
2099 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002100 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002101 } else {
2102 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002103 }
2104 }
2105 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002106 if dh.getCollectorIsRunning() {
2107 // Stop collector routine
2108 dh.stopCollector <- true
2109 }
Himani Chawla1472c682021-03-17 17:11:14 +05302110 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302111 dh.stopAlarmManager <- true
2112 }
2113
mpagenko80622a52021-02-09 16:53:23 +00002114 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00002115 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002116 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002117 lopOnuUpradeFsm := dh.pOnuUpradeFsm
2118 //lockUpgradeFsm must be release before cancellation as this may implicitly request removeOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002119 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002120 if lopOnuUpradeFsm != nil {
2121 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2122 }
mpagenko80622a52021-02-09 16:53:23 +00002123
mpagenko7d6bb022021-03-11 15:07:55 +00002124 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002125 return nil
2126}
2127
dbainbri4d3a0dc2020-12-02 00:33:42 +00002128func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2129 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 +05302130
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002131 // store persistent data collected during MIB upload processing
2132 if err := dh.storePersistentData(ctx); err != nil {
2133 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2134 log.Fields{"device-id": dh.deviceID, "err": err})
2135 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002136 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002137 dh.addAllUniPorts(ctx)
2138
mpagenkoa40e99a2020-11-17 13:50:39 +00002139 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2140 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2141 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2142 * disable/enable toggling here to allow traffic
2143 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2144 * like the py comment says:
2145 * # start by locking all the unis till mib sync and initial mib is downloaded
2146 * # this way we can capture the port down/up events when we are ready
2147 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302148
mpagenkoa40e99a2020-11-17 13:50:39 +00002149 // Init Uni Ports to Admin locked state
2150 // *** should generate UniLockStateDone event *****
2151 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002152 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002153 } else { //LockStateFSM already init
2154 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002155 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002156 }
2157}
2158
dbainbri4d3a0dc2020-12-02 00:33:42 +00002159func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2160 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302161 /* Mib download procedure -
2162 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2163 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002164 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002165 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002166 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002167 return
2168 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302169 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2170 if pMibDlFsm != nil {
2171 if pMibDlFsm.Is(dlStDisabled) {
2172 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002173 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 +05302174 // maybe try a FSM reset and then again ... - TODO!!!
2175 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002176 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302177 // maybe use more specific states here for the specific download steps ...
2178 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002179 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302180 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002181 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302182 //Begin MIB data download (running autonomously)
2183 }
2184 }
2185 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002186 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002187 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302188 // maybe try a FSM reset and then again ... - TODO!!!
2189 }
2190 /***** Mib download started */
2191 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002192 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302193 }
2194}
2195
dbainbri4d3a0dc2020-12-02 00:33:42 +00002196func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2197 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302198 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002199 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002200 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002201 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002202 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2203 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2204 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2205 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002206 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302207 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
2208 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002209 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302210 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002211 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302212 }
2213 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002214 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302215 log.Fields{"device-id": dh.deviceID})
2216 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002217 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002218
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002219 if !dh.getCollectorIsRunning() {
2220 // Start PM collector routine
2221 go dh.startCollector(ctx)
2222 }
2223 if !dh.getAlarmManagerIsRunning(ctx) {
2224 go dh.startAlarmManager(ctx)
2225 }
2226
Girish Gowdrae0140f02021-02-02 16:55:09 -08002227 // Initialize classical L2 PM Interval Counters
2228 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2229 // There is no way we should be landing here, but if we do then
2230 // there is nothing much we can do about this other than log error
2231 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2232 }
2233
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002234 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002235
2236 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2237 if pDevEntry == nil {
2238 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2239 return
2240 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002241 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002242 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002243 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002244 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2245 log.Fields{"device-id": dh.deviceID})
2246 go dh.reconcileDeviceTechProf(ctx)
2247 // reconcilement will be continued after ani config is done
2248 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002249 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002250 // *** should generate UniUnlockStateDone event *****
2251 if dh.pUnlockStateFsm == nil {
2252 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2253 } else { //UnlockStateFSM already init
2254 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2255 dh.runUniLockFsm(ctx, false)
2256 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302257 }
2258}
2259
dbainbri4d3a0dc2020-12-02 00:33:42 +00002260func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2261 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302262
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002263 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002264 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002265 raisedTs := time.Now().Unix()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002266 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2267 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002268 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002269 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002270 return
2271 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002272 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002273 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002274 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002275 if err := dh.storePersistentData(ctx); err != nil {
2276 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002277 log.Fields{"device-id": dh.deviceID, "err": err})
2278 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302279 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002280 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 +05302281 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002282 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002283 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302284 }
2285}
2286
dbainbri4d3a0dc2020-12-02 00:33:42 +00002287func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2288 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002289 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002290 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00002291 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
2292 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002293 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002294 }
2295
dbainbri4d3a0dc2020-12-02 00:33:42 +00002296 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002297 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002298 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002299
2300 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002301 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002302
dbainbri4d3a0dc2020-12-02 00:33:42 +00002303 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002304 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002305 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002306 return
2307 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002308 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002309 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002310 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002311 if err := dh.storePersistentData(ctx); err != nil {
2312 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002313 log.Fields{"device-id": dh.deviceID, "err": err})
2314 }
mpagenko900ee4b2020-10-12 11:56:34 +00002315}
2316
dbainbri4d3a0dc2020-12-02 00:33:42 +00002317func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2318 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002319 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002320 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002321 voltha.OperStatus_ACTIVE); err != nil {
2322 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002323 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002324 }
2325
dbainbri4d3a0dc2020-12-02 00:33:42 +00002326 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002327 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002328 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002329 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002330
2331 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002332 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002333
dbainbri4d3a0dc2020-12-02 00:33:42 +00002334 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002335 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002336 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002337 return
2338 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002339 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002340 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002341 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002342 if err := dh.storePersistentData(ctx); err != nil {
2343 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002344 log.Fields{"device-id": dh.deviceID, "err": err})
2345 }
mpagenko900ee4b2020-10-12 11:56:34 +00002346}
2347
dbainbri4d3a0dc2020-12-02 00:33:42 +00002348func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002349 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002350 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002351 // attention: the device reason update is done based on ONU-UNI-Port related activity
2352 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002353 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002354 // 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 +00002355 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302356 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002357 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002358 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002359 }
2360 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002361 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002362 // attention: the device reason update is done based on ONU-UNI-Port related activity
2363 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002364 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002365 // 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 +00002366 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002367 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002368 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302369}
2370
dbainbri4d3a0dc2020-12-02 00:33:42 +00002371func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2372 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002373 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302374 // attention: the device reason update is done based on ONU-UNI-Port related activity
2375 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302376
mpagenkof1fc3862021-02-16 10:09:52 +00002377 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002378 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002379 // which may be the case from some previous actvity on another UNI Port of the ONU
2380 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002381 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2382 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002383 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002384 }
2385 }
2386 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002387 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002388 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002389 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002390 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302391 }
mpagenkof1fc3862021-02-16 10:09:52 +00002392
2393 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2394 //events that request KvStore write
2395 if err := dh.storePersistentData(ctx); err != nil {
2396 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2397 log.Fields{"device-id": dh.deviceID, "err": err})
2398 }
2399 } else {
2400 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2401 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002402 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302403}
2404
Himani Chawla6d2ae152020-09-02 13:11:20 +05302405//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002406func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302407 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002408 case MibDatabaseSync:
2409 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002410 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002411 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002412 case UniLockStateDone:
2413 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002414 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002415 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002416 case MibDownloadDone:
2417 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002418 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002419 }
2420 case UniUnlockStateDone:
2421 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002422 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002423 }
mpagenko900ee4b2020-10-12 11:56:34 +00002424 case UniEnableStateDone:
2425 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002426 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002427 }
2428 case UniDisableStateDone:
2429 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002430 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002431 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002432 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002433 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002434 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002435 }
mpagenkof1fc3862021-02-16 10:09:52 +00002436 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002437 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002438 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002439 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002440 default:
2441 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002442 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002443 }
2444 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002445}
2446
dbainbri4d3a0dc2020-12-02 00:33:42 +00002447func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002448 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002449 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302450 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002451 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002452 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002453 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302454 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002455 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002456 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002457 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002458 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002459 //store UniPort with the System-PortNumber key
2460 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002461 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002462 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002463 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2464 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002465 } //error logging already within UniPort method
2466 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002467 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002468 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002469 }
2470 }
2471}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002472
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002473func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2474 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2475 if pDevEntry == nil {
2476 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2477 return
2478 }
2479 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2480 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2481 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2482 for _, mgmtEntityID := range pptpInstKeys {
2483 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2484 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2485 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2486 i++
2487 }
2488 } else {
2489 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2490 }
2491 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2492 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2493 for _, mgmtEntityID := range veipInstKeys {
2494 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2495 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2496 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2497 i++
2498 }
2499 } else {
2500 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2501 }
2502 if i == 0 {
2503 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2504 }
2505}
2506
mpagenko3af1f032020-06-10 08:53:41 +00002507// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002508func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002509 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302510 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002511 // with following remark:
2512 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2513 // # load on the core
2514
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002515 // 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 +00002516
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002517 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002518 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002519 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002520 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302521 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002522 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002523 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002524 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 +00002525 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002526 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002527 }
mpagenko3af1f032020-06-10 08:53:41 +00002528 }
2529 }
2530}
2531
2532// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002533func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002534 // compare enableUniPortStateUpdate() above
2535 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2536 for uniNo, uniPort := range dh.uniEntityMap {
2537 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002538
2539 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002540 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302541 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002542 if !dh.isReconciling() {
2543 //maybe also use getter functions on uniPort - perhaps later ...
2544 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2545 } else {
2546 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2547 }
2548
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002549 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002550 }
2551}
2552
2553// ONU_Active/Inactive announcement on system KAFKA bus
2554// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002555func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002556 var de voltha.DeviceEvent
2557 eventContext := make(map[string]string)
2558 //Populating event context
2559 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002560 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002561 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002562 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302563 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002564 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 +00002565 }
2566 oltSerialNumber := parentDevice.SerialNumber
2567
2568 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2569 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2570 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302571 eventContext["olt-serial-number"] = oltSerialNumber
2572 eventContext["device-id"] = aDeviceID
2573 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002574 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
2575 if deviceEntry := dh.getOnuDeviceEntry(ctx, false); deviceEntry != nil {
2576 deviceEntry.mutexPersOnuConfig.RLock()
2577 eventContext["equipment-id"] = deviceEntry.sOnuPersistentData.PersEquipmentID
2578 deviceEntry.mutexPersOnuConfig.RUnlock()
2579 eventContext["software-version"] = deviceEntry.getActiveImageVersion(ctx)
2580 deviceEntry.mutexPersOnuConfig.RLock()
2581 eventContext["vendor"] = deviceEntry.sOnuPersistentData.PersVendorID
2582 deviceEntry.mutexPersOnuConfig.RUnlock()
2583 eventContext["inactive-software-version"] = deviceEntry.getInactiveImageVersion(ctx)
2584 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2585 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2586 } else {
2587 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2588 log.Fields{"device-id": aDeviceID})
2589 return
2590 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002591
2592 /* Populating device event body */
2593 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302594 de.ResourceId = aDeviceID
2595 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002596 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2597 de.Description = fmt.Sprintf("%s Event - %s - %s",
2598 cEventObjectType, cOnuActivatedEvent, "Raised")
2599 } else {
2600 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2601 de.Description = fmt.Sprintf("%s Event - %s - %s",
2602 cEventObjectType, cOnuActivatedEvent, "Cleared")
2603 }
2604 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002605 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2606 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302607 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002608 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002609 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302610 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002611}
2612
Himani Chawla4d908332020-08-31 12:30:20 +05302613// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002614func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002615 chLSFsm := make(chan Message, 2048)
2616 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302617 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002618 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002619 sFsmName = "LockStateFSM"
2620 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002621 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002622 sFsmName = "UnLockStateFSM"
2623 }
mpagenko3af1f032020-06-10 08:53:41 +00002624
dbainbri4d3a0dc2020-12-02 00:33:42 +00002625 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002626 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002627 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002628 return
2629 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002630 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002631 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002632 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302633 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002634 dh.pLockStateFsm = pLSFsm
2635 } else {
2636 dh.pUnlockStateFsm = pLSFsm
2637 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002638 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002639 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002640 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002641 }
2642}
2643
2644// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002645func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002646 /* Uni Port lock/unlock procedure -
2647 ***** should run via 'adminDone' state and generate the argument requested event *****
2648 */
2649 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302650 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002651 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2652 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2653 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002654 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302655 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002656 }
2657 } else {
2658 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2659 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2660 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002661 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302662 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002663 }
2664 }
2665 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002666 if pLSStatemachine.Is(uniStDisabled) {
2667 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002668 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002669 // maybe try a FSM reset and then again ... - TODO!!!
2670 } else {
2671 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002672 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002673 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002674 }
2675 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002676 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002677 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002678 // maybe try a FSM reset and then again ... - TODO!!!
2679 }
2680 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002681 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002682 // maybe try a FSM reset and then again ... - TODO!!!
2683 }
2684}
2685
mpagenko80622a52021-02-09 16:53:23 +00002686// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002687func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002688 //in here lockUpgradeFsm is already locked
2689 chUpgradeFsm := make(chan Message, 2048)
2690 var sFsmName = "OnuSwUpgradeFSM"
2691 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002692 if apDevEntry.PDevOmciCC == nil {
2693 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2694 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002695 }
mpagenko15ff4a52021-03-02 10:09:20 +00002696 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002697 sFsmName, chUpgradeFsm)
2698 if dh.pOnuUpradeFsm != nil {
2699 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2700 if pUpgradeStatemachine != nil {
2701 if pUpgradeStatemachine.Is(upgradeStDisabled) {
2702 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2703 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2704 // maybe try a FSM reset and then again ... - TODO!!!
2705 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2706 }
2707 /***** LockStateFSM started */
mpagenko38662d02021-08-11 09:45:19 +00002708 //reset the last stored upgrade states
2709 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_STARTED //already with updated state
2710 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2711 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002712 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2713 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2714 } else {
2715 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2716 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2717 // maybe try a FSM reset and then again ... - TODO!!!
2718 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2719 }
2720 } else {
2721 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2722 // maybe try a FSM reset and then again ... - TODO!!!
2723 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2724 }
2725 } else {
2726 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2727 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2728 }
2729 return nil
2730}
2731
2732// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
mpagenko38662d02021-08-11 09:45:19 +00002733func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002734 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2735 "device-id": dh.deviceID})
2736 dh.lockUpgradeFsm.Lock()
mpagenko80622a52021-02-09 16:53:23 +00002737 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
mpagenko38662d02021-08-11 09:45:19 +00002738 dh.pLastUpgradeImageState = apImageState
2739 dh.lockUpgradeFsm.Unlock()
2740 //signal upgradeFsm removed using non-blocking channel send
2741 select {
2742 case dh.upgradeFsmChan <- struct{}{}:
2743 default:
2744 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
2745 "device-id": dh.deviceID})
2746 }
mpagenko80622a52021-02-09 16:53:23 +00002747}
2748
mpagenko15ff4a52021-03-02 10:09:20 +00002749// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2750func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2751 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2752 if pDevEntry == nil {
2753 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2754 return
2755 }
2756
2757 dh.lockUpgradeFsm.RLock()
2758 defer dh.lockUpgradeFsm.RUnlock()
2759 if dh.pOnuUpradeFsm != nil {
2760 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2761 if pUpgradeStatemachine != nil {
2762 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2763 // (some manual forced commit could do without)
mpagenko1f8e8822021-06-25 14:10:21 +00002764 upgradeState := pUpgradeStatemachine.Current()
2765 if (upgradeState == upgradeStWaitForCommit) ||
2766 (upgradeState == upgradeStRequestingActivate) {
2767 // also include upgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00002768 // 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 +00002769 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00002770 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
2771 if errImg != nil {
2772 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
2773 log.Fields{"device-id": dh.deviceID})
mpagenko38662d02021-08-11 09:45:19 +00002774 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
mpagenko15ff4a52021-03-02 10:09:20 +00002775 return
2776 }
mpagenko1f8e8822021-06-25 14:10:21 +00002777 if activeImageID == dh.pOnuUpradeFsm.inactiveImageMeID {
2778 if (upgradeState == upgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
2779 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
2780 if err := pUpgradeStatemachine.Event(upgradeEvActivationDone); err != nil {
2781 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
2782 return
2783 }
2784 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
2785 "state": upgradeState, "device-id": dh.deviceID})
2786 } else {
2787 //FSM in waitForCommit or (upgradeStRequestingActivate [lost ActivateResp] and commit allowed)
2788 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2789 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2790 return
2791 }
2792 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2793 "state": upgradeState, "device-id": dh.deviceID})
2794 }
2795 } else {
2796 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit/on ActivateResponse, but load did not start with expected image Id",
2797 log.Fields{"device-id": dh.deviceID})
mpagenko38662d02021-08-11 09:45:19 +00002798 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
mpagenko1f8e8822021-06-25 14:10:21 +00002799 return
2800 }
mpagenko15ff4a52021-03-02 10:09:20 +00002801 } else {
2802 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2803 log.Fields{"device-id": dh.deviceID})
mpagenko38662d02021-08-11 09:45:19 +00002804 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
mpagenko15ff4a52021-03-02 10:09:20 +00002805 return
2806 }
mpagenko183647c2021-06-08 15:25:04 +00002807 } else {
2808 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2809 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2810 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2811 if dh.pOnuUpradeFsm.inactiveImageMeID == activeImageID {
2812 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2813 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
mpagenko38662d02021-08-11 09:45:19 +00002814 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00002815 }
2816 }
mpagenko15ff4a52021-03-02 10:09:20 +00002817 }
2818 }
2819 } else {
2820 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2821 }
2822}
2823
Himani Chawla6d2ae152020-09-02 13:11:20 +05302824//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002825func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002826
2827 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002828 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07002829 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00002830 kvbackend := &db.Backend{
2831 Client: dh.pOpenOnuAc.kvClient,
2832 StoreType: dh.pOpenOnuAc.KVStoreType,
2833 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002834 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002835 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2836 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002837
mpagenkoaf801632020-07-03 10:00:42 +00002838 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002839}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002840func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302841 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002842
mpagenkodff5dda2020-08-28 11:52:01 +00002843 for _, field := range flow.GetOfbFields(apFlowItem) {
2844 switch field.Type {
2845 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2846 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002847 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002848 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2849 }
mpagenko01e726e2020-10-23 09:45:29 +00002850 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002851 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2852 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302853 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002854 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302855 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2856 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002857 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2858 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002859 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2860 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302861 return
mpagenkodff5dda2020-08-28 11:52:01 +00002862 }
2863 }
mpagenko01e726e2020-10-23 09:45:29 +00002864 */
mpagenkodff5dda2020-08-28 11:52:01 +00002865 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2866 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302867 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002868 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302869 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002870 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302871 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002872 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002873 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302874 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002875 }
2876 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2877 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302878 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002879 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002880 "PCP": loAddPcp})
2881 }
2882 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2883 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002884 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002885 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2886 }
2887 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2888 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002889 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002890 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2891 }
2892 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2893 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002894 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002895 "IPv4-DST": field.GetIpv4Dst()})
2896 }
2897 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2898 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002899 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002900 "IPv4-SRC": field.GetIpv4Src()})
2901 }
2902 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2903 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002904 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002905 "Metadata": field.GetTableMetadata()})
2906 }
2907 /*
2908 default:
2909 {
2910 //all other entires ignored
2911 }
2912 */
2913 }
2914 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302915}
mpagenkodff5dda2020-08-28 11:52:01 +00002916
dbainbri4d3a0dc2020-12-02 00:33:42 +00002917func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002918 for _, action := range flow.GetActions(apFlowItem) {
2919 switch action.Type {
2920 /* not used:
2921 case of.OfpActionType_OFPAT_OUTPUT:
2922 {
mpagenko01e726e2020-10-23 09:45:29 +00002923 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002924 "Output": action.GetOutput()})
2925 }
2926 */
2927 case of.OfpActionType_OFPAT_PUSH_VLAN:
2928 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002929 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002930 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2931 }
2932 case of.OfpActionType_OFPAT_SET_FIELD:
2933 {
2934 pActionSetField := action.GetSetField()
2935 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002936 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002937 "OxcmClass": pActionSetField.Field.OxmClass})
2938 }
2939 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302940 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002941 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302942 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002943 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302944 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002945 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302946 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002947 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002948 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002949 "Type": pActionSetField.Field.GetOfbField().Type})
2950 }
2951 }
2952 /*
2953 default:
2954 {
2955 //all other entires ignored
2956 }
2957 */
2958 }
2959 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302960}
2961
2962//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
ozgecanetsia82b91a62021-05-21 18:54:49 +03002963func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort,
2964 apFlowMetaData *voltha.FlowMetadata) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302965 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2966 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2967 var loAddPcp, loSetPcp uint8
2968 var loIPProto uint32
2969 /* the TechProfileId is part of the flow Metadata - compare also comment within
2970 * OLT-Adapter:openolt_flowmgr.go
2971 * Metadata 8 bytes:
2972 * Most Significant 2 Bytes = Inner VLAN
2973 * Next 2 Bytes = Tech Profile ID(TPID)
2974 * Least Significant 4 Bytes = Port ID
2975 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2976 * subscriber related flows.
2977 */
2978
dbainbri4d3a0dc2020-12-02 00:33:42 +00002979 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302980 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002981 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302982 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002983 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302984 }
mpagenko551a4d42020-12-08 18:09:20 +00002985 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002986 loCookie := apFlowItem.GetCookie()
2987 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002988 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002989 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302990
dbainbri4d3a0dc2020-12-02 00:33:42 +00002991 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002992 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302993 if loIPProto == 2 {
2994 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2995 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002996 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2997 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302998 return nil
2999 }
mpagenko01e726e2020-10-23 09:45:29 +00003000 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003001 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003002
3003 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003004 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003005 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
3006 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3007 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3008 //TODO!!: Use DeviceId within the error response to rwCore
3009 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00003010 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003011 }
3012 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003013 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003014 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3015 } else {
3016 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3017 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3018 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303019 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003020 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003021 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003022 }
mpagenko9a304ea2020-12-16 15:54:01 +00003023
3024 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenko7d14de12021-07-27 08:31:56 +00003025 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3026 // when different rules are requested concurrently for the same uni
3027 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3028 dh.lockVlanConfig.Lock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003029 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID, "tpID": loTpID, "uniID": apUniPort.uniID})
3030 var meter *voltha.OfpMeterConfig
3031 if apFlowMetaData != nil {
3032 meter = apFlowMetaData.Meters[0]
3033 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303034 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003035 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003036 loMatchVlan, loSetVlan, loSetPcp, false, meter)
mpagenko7d14de12021-07-27 08:31:56 +00003037 dh.lockVlanConfig.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +00003038 return err
mpagenkodff5dda2020-08-28 11:52:01 +00003039 }
mpagenko7d14de12021-07-27 08:31:56 +00003040 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003041 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false, meter)
mpagenko7d14de12021-07-27 08:31:56 +00003042 dh.lockVlanConfig.Unlock()
3043 return err
mpagenko01e726e2020-10-23 09:45:29 +00003044}
3045
3046//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00003047func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00003048 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3049 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3050 //no extra check is done on the rule parameters
3051 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3052 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3053 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3054 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003055 // - 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 +00003056 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003057 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003058
3059 /* TT related temporary workaround - should not be needed anymore
3060 for _, field := range flow.GetOfbFields(apFlowItem) {
3061 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3062 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00003063 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003064 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3065 if loIPProto == 2 {
3066 // 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 +00003067 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00003068 log.Fields{"device-id": dh.deviceID})
3069 return nil
3070 }
3071 }
3072 } //for all OfbFields
3073 */
3074
mpagenko9a304ea2020-12-16 15:54:01 +00003075 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003076 dh.lockVlanConfig.RLock()
3077 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00003078 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003079 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00003080 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003081 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00003082 log.Fields{"device-id": dh.deviceID})
3083 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003084 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00003085 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00003086
mpagenko01e726e2020-10-23 09:45:29 +00003087 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00003088}
3089
Himani Chawla26e555c2020-08-31 12:30:20 +05303090// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003091// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003092// precondition: dh.lockVlanConfig is locked by the caller!
mpagenko551a4d42020-12-08 18:09:20 +00003093func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003094 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
mpagenkodff5dda2020-08-28 11:52:01 +00003095 chVlanFilterFsm := make(chan Message, 2048)
3096
dbainbri4d3a0dc2020-12-02 00:33:42 +00003097 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003098 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003099 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303100 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003101 }
3102
dbainbri4d3a0dc2020-12-02 00:33:42 +00003103 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00003104 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003105 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter)
mpagenkodff5dda2020-08-28 11:52:01 +00003106 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003107 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3108 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Himani Chawla26e555c2020-08-31 12:30:20 +05303109 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003110 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3111 if pVlanFilterStatemachine != nil {
3112 if pVlanFilterStatemachine.Is(vlanStDisabled) {
3113 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003114 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05303115 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003116 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303117 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003118 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05303119 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3120 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003121 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003122 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003123 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303124 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003125 }
3126 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003127 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003128 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303129 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003130 }
3131 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003132 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003133 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05303134 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003135 }
3136 return nil
3137}
3138
mpagenkofc4f56e2020-11-04 17:17:49 +00003139//VerifyVlanConfigRequest checks on existence of a given uniPort
3140// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003141func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003142 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
3143 var pCurrentUniPort *onuUniPort
3144 for _, uniPort := range dh.uniEntityMap {
3145 // only if this port is validated for operState transfer
3146 if uniPort.uniID == uint8(aUniID) {
3147 pCurrentUniPort = uniPort
3148 break //found - end search loop
3149 }
3150 }
3151 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003152 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00003153 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
3154 return
3155 }
mpagenko551a4d42020-12-08 18:09:20 +00003156 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003157}
3158
mpagenkodff5dda2020-08-28 11:52:01 +00003159//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00003160func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003161 //TODO!! verify and start pending flow configuration
3162 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3163 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003164
3165 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303166 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003167 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003168 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
3169 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3170 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003171 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
3172 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
3173 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
3174 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
3175 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3176 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3177 } else {
3178 /***** UniVlanConfigFsm continued */
3179 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
3180 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3181 "UniPort": apUniPort.portNo})
3182 }
3183 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
3184 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
3185 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3186 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3187 } else {
3188 /***** UniVlanConfigFsm continued */
3189 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3190 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3191 "UniPort": apUniPort.portNo})
3192 }
mpagenkodff5dda2020-08-28 11:52:01 +00003193 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003194 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3195 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003196 "UniPort": apUniPort.portNo})
3197 }
3198 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003199 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3200 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3201 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003202 }
3203 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003204 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003205 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003206 }
mpagenkof1fc3862021-02-16 10:09:52 +00003207 } else {
3208 dh.lockVlanConfig.RUnlock()
3209 }
mpagenkodff5dda2020-08-28 11:52:01 +00003210}
3211
3212//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3213// 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 +00003214func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3215 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003216 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3217 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003218 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303219 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003220 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003221}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003222
mpagenkof1fc3862021-02-16 10:09:52 +00003223//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3224func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3225 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3226 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3227 // obviously then parallel processing on the cancel must be avoided
3228 // deadline context to ensure completion of background routines waited for
3229 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3230 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3231 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3232
3233 aPDevEntry.resetKvProcessingErrorIndication()
3234 var wg sync.WaitGroup
3235 wg.Add(1) // for the 1 go routine to finish
3236
3237 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3238 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3239
3240 return aPDevEntry.getKvProcessingErrorIndication()
3241}
3242
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003243//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3244//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003245func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3246 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003247
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003248 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003249 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003250 return nil
3251 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003252 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003253
dbainbri4d3a0dc2020-12-02 00:33:42 +00003254 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003255 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003256 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003257 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3258 }
3259 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3260
mpagenkof1fc3862021-02-16 10:09:52 +00003261 if aWriteToKvStore {
3262 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3263 }
3264 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003265}
3266
dbainbri4d3a0dc2020-12-02 00:33:42 +00003267func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003268 defer cancel() //ensure termination of context (may be pro forma)
3269 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003270 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003271 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003272}
3273
dbainbri4d3a0dc2020-12-02 00:33:42 +00003274func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003275
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003276 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003277 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003278 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003279 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3280 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003281 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003282 return err
3283 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003284 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003285 return nil
3286 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003287 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003288 return nil
3289}
3290
dbainbri4d3a0dc2020-12-02 00:33:42 +00003291func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3292 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003293 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003294 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003295 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3296 }
mpagenkof1fc3862021-02-16 10:09:52 +00003297 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003298}
3299
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003300// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003301// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003302func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3303 dh.lockDevice.RLock()
3304 defer dh.lockDevice.RUnlock()
3305 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3306 return uniPort.entityID, nil
3307 }
3308 return 0, errors.New("error-fetching-uni-port")
3309}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003310
3311// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003312func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3313 var errorsList []error
3314 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 -08003315
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003316 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3317 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3318 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3319
3320 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3321 // successfully.
3322 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3323 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3324 if len(errorsList) > 0 {
3325 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3326 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003327 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003328 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3329 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003330}
3331
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003332func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3333 var err error
3334 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003335 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003336
3337 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3338 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3339 errorsList = append(errorsList, err)
3340 }
3341 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003342 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003343
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003344 return errorsList
3345}
3346
3347func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3348 var err error
3349 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003350 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003351 // Check if group metric related config is updated
3352 for _, v := range pmConfigs.Groups {
3353 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3354 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3355 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3356
3357 if ok && m.frequency != v.GroupFreq {
3358 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3359 errorsList = append(errorsList, err)
3360 }
3361 }
3362 if ok && m.enabled != v.Enabled {
3363 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3364 errorsList = append(errorsList, err)
3365 }
3366 }
3367 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003368 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003369 return errorsList
3370}
3371
3372func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3373 var err error
3374 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003375 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003376 // Check if standalone metric related config is updated
3377 for _, v := range pmConfigs.Metrics {
3378 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003379 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003380 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3381
3382 if ok && m.frequency != v.SampleFreq {
3383 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3384 errorsList = append(errorsList, err)
3385 }
3386 }
3387 if ok && m.enabled != v.Enabled {
3388 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3389 errorsList = append(errorsList, err)
3390 }
3391 }
3392 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003393 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003394 return errorsList
3395}
3396
3397// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003398func (dh *deviceHandler) startCollector(ctx context.Context) {
3399 logger.Debugf(ctx, "startingCollector")
3400
3401 // Start routine to process OMCI GET Responses
3402 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303403 // Create Extended Frame PM ME
3404 go dh.pOnuMetricsMgr.createEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003405 // Initialize the next metric collection time.
3406 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3407 // reset like onu rebooted.
3408 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003409 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003410 for {
3411 select {
3412 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003413 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003414 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003415 // Stop the L2 PM FSM
3416 go func() {
3417 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3418 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3419 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3420 }
3421 } else {
3422 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3423 }
3424 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003425 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3426 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3427 }
3428 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3429 dh.pOnuMetricsMgr.stopTicks <- true
3430 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003431
Girish Gowdrae09a6202021-01-12 18:10:59 -08003432 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003433 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3434 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3435 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3436 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3437 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003438 // Update the next metric collection time.
3439 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003440 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003441 } else {
3442 if dh.pmConfigs.Grouped { // metrics are managed as a group
3443 // parse through the group and standalone metrics to see it is time to collect their metrics
3444 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003445
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003446 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3447 // 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 -08003448 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3449 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003450 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3451 }
3452 }
3453 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3454 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3455 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3456 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3457 }
3458 }
3459 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3460
3461 // parse through the group and update the next metric collection time
3462 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3463 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3464 // 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 -08003465 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3466 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003467 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3468 }
3469 }
3470 // parse through the standalone metrics and update the next metric collection time
3471 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3472 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3473 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3474 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3475 }
3476 }
3477 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3478 } /* else { // metrics are not managed as a group
3479 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3480 } */
3481 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003482 }
3483 }
3484}
kesavandfdf77632021-01-26 23:40:33 -05003485
3486func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3487
3488 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3489 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3490}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003491
Himani Chawla43f95ff2021-06-03 00:24:12 +05303492func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3493 if dh.pOnuMetricsMgr == nil {
3494 return &extension.SingleGetValueResponse{
3495 Response: &extension.GetValueResponse{
3496 Status: extension.GetValueResponse_ERROR,
3497 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3498 },
3499 }
3500 }
3501 resp := dh.pOnuMetricsMgr.collectEthernetFrameExtendedPMCounters(ctx)
3502 return resp
3503}
3504
mpagenkof1fc3862021-02-16 10:09:52 +00003505func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3506 if pFsm == nil {
3507 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003508 }
mpagenkof1fc3862021-02-16 10:09:52 +00003509 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003510}
3511
mpagenkof1fc3862021-02-16 10:09:52 +00003512func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3513 var pFsm *fsm.FSM
3514 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3515 switch omciFsm {
3516 case cUploadFsm:
3517 {
3518 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3519 }
3520 case cDownloadFsm:
3521 {
3522 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3523 }
3524 case cUniLockFsm:
3525 {
3526 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3527 }
3528 case cUniUnLockFsm:
3529 {
3530 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3531 }
3532 case cL2PmFsm:
3533 {
3534 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3535 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3536 } else {
3537 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003538 }
3539 }
mpagenko80622a52021-02-09 16:53:23 +00003540 case cOnuUpgradeFsm:
3541 {
3542 dh.lockUpgradeFsm.RLock()
3543 defer dh.lockUpgradeFsm.RUnlock()
3544 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3545 }
mpagenkof1fc3862021-02-16 10:09:52 +00003546 default:
3547 {
3548 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3549 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3550 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003551 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003552 }
mpagenkof1fc3862021-02-16 10:09:52 +00003553 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003554}
3555
mpagenkof1fc3862021-02-16 10:09:52 +00003556func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3557 for _, v := range dh.pOnuTP.pAniConfigFsm {
3558 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003559 return false
3560 }
3561 }
3562 return true
3563}
3564
mpagenkof1fc3862021-02-16 10:09:52 +00003565func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3566 dh.lockVlanConfig.RLock()
3567 defer dh.lockVlanConfig.RUnlock()
3568 for _, v := range dh.UniVlanConfigFsmMap {
3569 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3570 return false
3571 }
3572 }
3573 return true //FSM not active - so there is no activity on omci
3574}
3575
3576func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3577 dh.lockVlanConfig.RLock()
3578 defer dh.lockVlanConfig.RUnlock()
3579 for _, v := range dh.UniVlanConfigFsmMap {
3580 if v.pAdaptFsm.pFsm != nil {
3581 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3582 return true //there is at least one VLAN FSM with some active configuration
3583 }
3584 }
3585 }
3586 return false //there is no VLAN FSM with some active configuration
3587}
3588
3589func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3590 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3591 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3592 return false
3593 }
3594 }
3595 // a further check is done to identify, if at least some data traffic related configuration exists
3596 // 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])
3597 return dh.checkUserServiceExists(ctx)
3598}
3599
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003600func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3601 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3602 if err := dh.resetFsms(ctx, false); err != nil {
3603 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3604 // TODO: fatal error reset ONU, delete deviceHandler!
3605 return
3606 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003607 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003608 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003609}
3610
3611func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3612 dh.mutexCollectorFlag.Lock()
3613 dh.collectorIsRunning = flagValue
3614 dh.mutexCollectorFlag.Unlock()
3615}
3616
3617func (dh *deviceHandler) getCollectorIsRunning() bool {
3618 dh.mutexCollectorFlag.RLock()
3619 flagValue := dh.collectorIsRunning
3620 dh.mutexCollectorFlag.RUnlock()
3621 return flagValue
3622}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303623
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303624func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3625 dh.mutextAlarmManagerFlag.Lock()
3626 dh.alarmManagerIsRunning = flagValue
3627 dh.mutextAlarmManagerFlag.Unlock()
3628}
3629
Himani Chawla1472c682021-03-17 17:11:14 +05303630func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303631 dh.mutextAlarmManagerFlag.RLock()
3632 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303633 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303634 dh.mutextAlarmManagerFlag.RUnlock()
3635 return flagValue
3636}
3637
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303638func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3639 logger.Debugf(ctx, "startingAlarmManager")
3640
3641 // Start routine to process OMCI GET Responses
3642 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303643 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303644 if stop := <-dh.stopAlarmManager; stop {
3645 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303646 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303647 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303648 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3649 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3650 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303651 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303652 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303653 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3654 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303655 }
3656}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003657
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003658func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003659 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003660
Maninder7961d722021-06-16 22:10:28 +05303661 connectStatus := voltha.ConnectStatus_UNREACHABLE
3662 operState := voltha.OperStatus_UNKNOWN
3663
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003664 if !dh.isReconciling() {
3665 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003666 logger.Debugw(ctx, "wait for channel signal or timeout",
3667 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003668 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003669 case success := <-dh.chReconcilingFinished:
3670 if success {
Maninderb5187552021-03-23 22:23:42 +05303671 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3672 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3673 log.Fields{"device-id": dh.deviceID})
3674 } else {
Maninderb5187552021-03-23 22:23:42 +05303675 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3676 connectStatus = voltha.ConnectStatus_REACHABLE
3677 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3678 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3679 operState = voltha.OperStatus_ACTIVE
3680 } else {
3681 operState = voltha.OperStatus_ACTIVATING
3682 }
3683 }
3684 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3685 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3686 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3687 operState = voltha.OperStatus_DISCOVERED
3688 }
3689
3690 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303691 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003692 logger.Debugw(ctx, "reconciling has been finished in time",
3693 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303694 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, operState); err != nil {
3695 logger.Errorw(ctx, "unable to update device state to core",
3696 log.Fields{"device-id": dh.deviceID, "Err": err})
3697 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003698 } else {
Maninderb5187552021-03-23 22:23:42 +05303699 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003700 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303701
3702 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3703 logger.Errorw(ctx, "No valid OnuDevice",
3704 log.Fields{"device-id": dh.deviceID})
3705 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3706 connectStatus = voltha.ConnectStatus_REACHABLE
3707 }
3708
3709 dh.deviceReconcileFailedUpdate(ctx, drReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003710 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003711 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003712 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3713 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303714
3715 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3716 logger.Errorw(ctx, "No valid OnuDevice",
3717 log.Fields{"device-id": dh.deviceID})
3718 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3719 connectStatus = voltha.ConnectStatus_REACHABLE
3720 }
3721
3722 dh.deviceReconcileFailedUpdate(ctx, drReconcileMaxTimeout, connectStatus)
3723
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003724 }
3725 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003726 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003727 dh.mutexReconcilingFlag.Unlock()
3728 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003729 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003730 dh.mutexReconcilingFlag.Lock()
3731 if skipOnuConfig {
3732 dh.reconciling = cSkipOnuConfigReconciling
3733 } else {
3734 dh.reconciling = cOnuConfigReconciling
3735 }
3736 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003737}
3738
Girish Gowdra50e56422021-06-01 16:46:04 -07003739func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool) {
3740 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID, "success": success})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003741 if dh.isReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07003742 dh.chReconcilingFinished <- success
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003743 } else {
3744 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3745 }
3746}
3747
3748func (dh *deviceHandler) isReconciling() bool {
3749 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003750 defer dh.mutexReconcilingFlag.RUnlock()
3751 return dh.reconciling != cNoReconciling
3752}
3753
3754func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3755 dh.mutexReconcilingFlag.RLock()
3756 defer dh.mutexReconcilingFlag.RUnlock()
3757 return dh.reconciling == cSkipOnuConfigReconciling
3758}
3759
3760func (dh *deviceHandler) setDeviceReason(value uint8) {
3761 dh.mutexDeviceReason.Lock()
3762 dh.deviceReason = value
3763 dh.mutexDeviceReason.Unlock()
3764}
3765
3766func (dh *deviceHandler) getDeviceReason() uint8 {
3767 dh.mutexDeviceReason.RLock()
3768 value := dh.deviceReason
3769 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003770 return value
3771}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003772
3773func (dh *deviceHandler) getDeviceReasonString() string {
3774 return deviceReasonMap[dh.getDeviceReason()]
3775}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003776
3777func (dh *deviceHandler) setReconcilingFlows(value bool) {
3778 dh.mutexReconcilingFlowsFlag.Lock()
3779 dh.reconcilingFlows = value
3780 dh.mutexReconcilingFlowsFlag.Unlock()
3781}
3782
3783func (dh *deviceHandler) isReconcilingFlows() bool {
3784 dh.mutexReconcilingFlowsFlag.RLock()
3785 value := dh.reconcilingFlows
3786 dh.mutexReconcilingFlowsFlag.RUnlock()
3787 return value
3788}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003789
3790func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3791 dh.mutexReadyForOmciConfig.Lock()
3792 dh.readyForOmciConfig = flagValue
3793 dh.mutexReadyForOmciConfig.Unlock()
3794}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003795func (dh *deviceHandler) isReadyForOmciConfig() bool {
3796 dh.mutexReadyForOmciConfig.RLock()
3797 flagValue := dh.readyForOmciConfig
3798 dh.mutexReadyForOmciConfig.RUnlock()
3799 return flagValue
3800}
Maninder7961d722021-06-16 22:10:28 +05303801
3802func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
3803 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
3804 logger.Errorw(ctx, "unable to update device reason to core",
3805 log.Fields{"device-id": dh.deviceID, "Err": err})
3806 }
3807
3808 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
3809 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, voltha.OperStatus_RECONCILING_FAILED); err != nil {
3810 logger.Errorw(ctx, "unable to update device state to core",
3811 log.Fields{"device-id": dh.deviceID, "Err": err})
3812 }
3813}