blob: cfe99c92ee5b9055e4680dc0ef913fd528608333 [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
mpagenkobc4170a2021-08-17 16:42:10 +0000221 lockVlanAdd sync.RWMutex
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000222 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
223 lockUpgradeFsm sync.RWMutex
224 pOnuUpradeFsm *OnuUpgradeFsm
225 reconciling uint8
226 mutexReconcilingFlag sync.RWMutex
227 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000228 reconcilingFlows bool
229 mutexReconcilingFlowsFlag sync.RWMutex
230 chReconcilingFlowsFinished chan bool //channel to indicate that reconciling of flows has been finished
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000231 mutexReadyForOmciConfig sync.RWMutex
232 readyForOmciConfig bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000233 deletionInProgress bool
234 mutexDeletionInProgressFlag sync.RWMutex
mpagenko38662d02021-08-11 09:45:19 +0000235 pLastUpgradeImageState *voltha.ImageState
236 upgradeFsmChan chan struct{}
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000237}
238
Himani Chawla6d2ae152020-09-02 13:11:20 +0530239//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530240func 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 +0530241 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000242 dh.coreProxy = cp
243 dh.AdapterProxy = ap
244 dh.EventProxy = ep
245 cloned := (proto.Clone(device)).(*voltha.Device)
246 dh.deviceID = cloned.Id
247 dh.DeviceType = cloned.Type
248 dh.adminState = "up"
249 dh.device = cloned
250 dh.pOpenOnuAc = adapter
251 dh.exitChannel = make(chan int, 1)
252 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000253 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000254 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000255 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530256 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530257 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000258 dh.stopHeartbeatCheck = make(chan bool, 2)
259 //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 +0000260 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530261 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000262 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000263 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000264 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000265 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000266 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000267 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000268 dh.reconcilingFlows = false
269 dh.chReconcilingFlowsFinished = make(chan bool)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000270 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000271 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000272 dh.pLastUpgradeImageState = &voltha.ImageState{
273 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
274 Reason: voltha.ImageState_UNKNOWN_ERROR,
275 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
276 }
277 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000278
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800279 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
280 dh.pmConfigs = cloned.PmConfigs
281 } /* else {
282 // will be populated when onu_metrics_mananger is initialized.
283 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800284
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000285 // Device related state machine
286 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000287 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000288 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000289 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
290 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
291 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
292 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
293 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000294 },
295 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000296 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
297 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
298 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
299 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
300 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
301 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
302 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
303 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000304 },
305 )
mpagenkoaf801632020-07-03 10:00:42 +0000306
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000307 return &dh
308}
309
Himani Chawla6d2ae152020-09-02 13:11:20 +0530310// start save the device to the data model
311func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000312 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000313 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000314 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000315}
316
Himani Chawla4d908332020-08-31 12:30:20 +0530317/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000318// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530319func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000320 logger.Debug("stopping-device-handler")
321 dh.exitChannel <- 1
322}
Himani Chawla4d908332020-08-31 12:30:20 +0530323*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000324
325// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530326// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000327
Girish Gowdrae0140f02021-02-02 16:55:09 -0800328//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530329func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000330 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000331
dbainbri4d3a0dc2020-12-02 00:33:42 +0000332 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000333 if dh.pDeviceStateFsm.Is(devStNull) {
334 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000335 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000336 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000337 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800338 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
339 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800340 // Now, set the initial PM configuration for that device
341 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
342 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
343 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800344 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000345 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000346 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000347 }
348
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000349}
350
mpagenko057889c2021-01-21 16:51:58 +0000351func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530352 msgBody := msg.GetBody()
353 omciMsg := &ic.InterAdapterOmciMessage{}
354 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000355 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530356 "device-id": dh.deviceID, "error": err})
357 return err
358 }
359
mpagenko80622a52021-02-09 16:53:23 +0000360 /* 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 +0530361 //assuming omci message content is hex coded!
362 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000363 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530364 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000365 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000366 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530367 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000368 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000369 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000370 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000371 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 +0530372 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000373 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000374 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530375}
376
Himani Chawla6d2ae152020-09-02 13:11:20 +0530377func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000378 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530379 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000380
dbainbri4d3a0dc2020-12-02 00:33:42 +0000381 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000382
dbainbri4d3a0dc2020-12-02 00:33:42 +0000383 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000384 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000385 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000386 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
387 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530388 if dh.pOnuTP == nil {
389 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000390 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530391 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000392 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530393 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000394 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000395 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000396 "device-state": dh.getDeviceReasonString()})
397 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530398 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000399 //previous state test here was just this one, now extended for more states to reject the SetRequest:
400 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
401 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530402
403 msgBody := msg.GetBody()
404 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
405 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000406 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530407 "device-id": dh.deviceID, "error": err})
408 return err
409 }
410
411 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000412 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
413 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530414 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000415 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000416
417 if techProfMsg.UniId > 255 {
418 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
419 techProfMsg.UniId, dh.deviceID))
420 }
421 uniID := uint8(techProfMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700422 tpID, err := GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800423 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700424 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800425 return err
426 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700427 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000428
Girish Gowdra50e56422021-06-01 16:46:04 -0700429 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530430
Girish Gowdra50e56422021-06-01 16:46:04 -0700431 switch tpInst := techProfMsg.TechTpInstance.(type) {
432 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance:
433 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
434 // if there has been some change for some uni TechProfilePath
435 //in order to allow concurrent calls to other dh instances we do not wait for execution here
436 //but doing so we can not indicate problems to the caller (who does what with that then?)
437 //by now we just assume straightforward successful execution
438 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
439 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530440
Girish Gowdra50e56422021-06-01 16:46:04 -0700441 // deadline context to ensure completion of background routines waited for
442 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
443 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
444 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000445
Girish Gowdra50e56422021-06-01 16:46:04 -0700446 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
447
448 var wg sync.WaitGroup
449 wg.Add(1) // for the 1 go routine to finish
450 // attention: deadline completion check and wg.Done is to be done in both routines
451 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
452 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
453 if tpErr := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
454 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.deviceID, "err": tpErr, "tp-path": techProfMsg.TpInstancePath})
455 return tpErr
456 }
457 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
458 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
459 pDevEntry.resetKvProcessingErrorIndication()
460 wg.Add(1) // for the 1 go routine to finish
461 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
462 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
463 if kvErr := pDevEntry.getKvProcessingErrorIndication(); kvErr != nil {
464 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.deviceID, "err": kvErr, "tp-path": techProfMsg.TpInstancePath})
465 return kvErr
466 }
467 return nil
468 default:
469 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"tp-path": techProfMsg.TpInstancePath})
470 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700471 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530472 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000473 // no change, nothing really to do - return success
Girish Gowdra50e56422021-06-01 16:46:04 -0700474 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 +0530475 return nil
476}
477
Himani Chawla6d2ae152020-09-02 13:11:20 +0530478func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000479 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530480 msg *ic.InterAdapterMessage) error {
481
482 if dh.pOnuTP == nil {
483 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000484 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530485 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000486 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530487 }
488
489 msgBody := msg.GetBody()
490 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
491 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000492 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530493 "device-id": dh.deviceID, "error": err})
494 return err
495 }
496
497 //compare TECH_PROFILE_DOWNLOAD_REQUEST
498 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000499 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530500
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000501 if delGemPortMsg.UniId > 255 {
502 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
503 delGemPortMsg.UniId, dh.deviceID))
504 }
505 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700506 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800507 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700508 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 -0800509 return err
510 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700511 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 +0000512 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000513
Mahir Gunyel9545be22021-07-04 15:53:16 -0700514 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
515 cResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000516
Himani Chawla26e555c2020-08-31 12:30:20 +0530517}
518
Himani Chawla6d2ae152020-09-02 13:11:20 +0530519func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000520 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530521 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000522
dbainbri4d3a0dc2020-12-02 00:33:42 +0000523 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000524 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000525 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000526 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
527 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530528 if dh.pOnuTP == nil {
529 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000530 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530531 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000532 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530533 }
534
535 msgBody := msg.GetBody()
536 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
537 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000538 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530539 "device-id": dh.deviceID, "error": err})
540 return err
541 }
542
543 //compare TECH_PROFILE_DOWNLOAD_REQUEST
544 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000545 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000546
547 if delTcontMsg.UniId > 255 {
548 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
549 delTcontMsg.UniId, dh.deviceID))
550 }
551 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700552 tpPath := delTcontMsg.TpInstancePath
Girish Gowdra041dcb32020-11-16 16:54:30 -0800553 tpID, err := GetTpIDFromTpPath(tpPath)
554 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000555 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800556 return err
557 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700558 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 +0000559
Mahir Gunyel9545be22021-07-04 15:53:16 -0700560 pDevEntry.freeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530561
Mahir Gunyel9545be22021-07-04 15:53:16 -0700562 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
563 cResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000564
Mahir Gunyel9545be22021-07-04 15:53:16 -0700565}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000566
Mahir Gunyel9545be22021-07-04 15:53:16 -0700567func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
568 uniID uint8, tpID uint8, pathString string, resource resourceEntry, entryID uint32) error {
569 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
570 if pDevEntry == nil {
571 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
572 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530573 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700574 var resourceName string
575 if cResourceGemPort == resource {
576 resourceName = "Gem"
577 } else {
578 resourceName = "Tcont"
579 }
580
581 // deadline context to ensure completion of background routines waited for
582 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
583 dctx, cancel := context.WithDeadline(context.Background(), deadline)
584
585 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
586
587 var wg sync.WaitGroup
588 wg.Add(1) // for the 1 go routine to finish
589 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
590 resource, entryID, &wg)
591 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
592 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); err != nil {
593 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
594 return err
595 }
596
597 if dh.pOnuTP.isTechProfileConfigCleared(ctx, uniID, tpID) {
598 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID})
599 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
600 pDevEntry.resetKvProcessingErrorIndication()
601 var wg2 sync.WaitGroup
602 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
603 wg2.Add(1)
604 // Removal of the gem id mapping represents the removal of the tech profile
605 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID})
606 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
607 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
608 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
609 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
610 return err
611 }
612 }
613 }
614 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.deviceID,
615 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530616 return nil
617}
618
Himani Chawla6d2ae152020-09-02 13:11:20 +0530619//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000620// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
621// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000622func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000623 msgID := msg.Header.Id
624 msgType := msg.Header.Type
625 fromTopic := msg.Header.FromTopic
626 toTopic := msg.Header.ToTopic
627 toDeviceID := msg.Header.ToDeviceId
628 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000629 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000630 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
631
632 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000633 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000634 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
635 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000636 {
mpagenko057889c2021-01-21 16:51:58 +0000637 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000638 }
mpagenkoaf801632020-07-03 10:00:42 +0000639 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
640 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000641 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000642 }
643 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
644 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000645 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000646
mpagenkoaf801632020-07-03 10:00:42 +0000647 }
648 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
649 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000650 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000651 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000652 default:
653 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000654 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000655 "msgType": msg.Header.Type, "device-id": dh.deviceID})
656 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000657 }
658 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000659}
660
mpagenkodff5dda2020-08-28 11:52:01 +0000661//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000662func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
663 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000664 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
ozgecanetsia82b91a62021-05-21 18:54:49 +0300665 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID, "metadata": apFlowMetaData})
mpagenko01e726e2020-10-23 09:45:29 +0000666 var retError error = nil
667 //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 +0000668 if apOfFlowChanges.ToRemove != nil {
669 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000670 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000671 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000672 "device-id": dh.deviceID})
673 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000674 continue
675 }
676 flowInPort := flow.GetInPort(flowItem)
677 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000678 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 +0000679 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
680 continue
681 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000682 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000683 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000684 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000685 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000686 continue
687 } else {
688 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530689 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000690 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
691 loUniPort = uniPort
692 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000693 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000694 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
695 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
696 flowInPort, dh.deviceID)
697 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000698 }
699 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000700 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000701 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000702 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000703 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000704 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000705 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000706 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000707 log.Fields{"device-id": dh.deviceID, "error": err})
708 retError = err
709 continue
710 //return err
711 } else { // if last setting succeeds, overwrite possibly previously set error
712 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000713 }
714 }
715 }
716 }
mpagenko01e726e2020-10-23 09:45:29 +0000717 if apOfFlowChanges.ToAdd != nil {
718 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
719 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000720 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000721 "device-id": dh.deviceID})
722 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
723 continue
724 }
725 flowInPort := flow.GetInPort(flowItem)
726 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 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 +0000728 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
729 continue
730 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
731 } else if flowInPort == dh.ponPortNumber {
732 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000733 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000734 "device-id": dh.deviceID, "inPort": flowInPort})
735 continue
736 } else {
737 // this is the relevant upstream flow
738 var loUniPort *onuUniPort
739 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
740 loUniPort = uniPort
741 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000742 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000743 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
744 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
745 flowInPort, dh.deviceID)
746 continue
747 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
748 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000749 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
750 // if not, we just throw some error here to have an indication about that, if we really need to support that
751 // then we would need to create some means to activate the internal stored flows
752 // after the device gets active automatically (and still with its dependency to the TechProfile)
753 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
754 // also abort for the other still possible flows here
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000755 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000756 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000757 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000758 return fmt.Errorf("improper device state on device %s", dh.deviceID)
759 }
760
mpagenko01e726e2020-10-23 09:45:29 +0000761 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000762 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000763 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
764 "uniPortName": loUniPort.name})
ozgecanetsia82b91a62021-05-21 18:54:49 +0300765 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort, apFlowMetaData)
mpagenko01e726e2020-10-23 09:45:29 +0000766 //try next flow after processing error
767 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000768 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000769 log.Fields{"device-id": dh.deviceID, "error": err})
770 retError = err
771 continue
772 //return err
773 } else { // if last setting succeeds, overwrite possibly previously set error
774 retError = nil
775 }
776 }
777 }
778 }
779 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000780}
781
Himani Chawla6d2ae152020-09-02 13:11:20 +0530782//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000783//following are the expected device states after this activity:
784//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
785// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000786func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
787 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000788
mpagenko900ee4b2020-10-12 11:56:34 +0000789 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000790 //note that disableDevice sequences in some 'ONU active' state may yield also
791 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000792 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000793 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000794 //disable-device shall be just a UNi/ONU-G related admin state setting
795 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000796
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000797 if dh.isReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000798 // disable UNI ports/ONU
799 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
800 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000801 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000802 } else { //LockStateFSM already init
803 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000804 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000805 }
806 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000807 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000808 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000809 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000810 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
811 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000812 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000813 }
mpagenko01e726e2020-10-23 09:45:29 +0000814 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000815
816 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000817 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000818 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300819 }
820}
821
Himani Chawla6d2ae152020-09-02 13:11:20 +0530822//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000823func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
824 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000825
mpagenkoaa3afe92021-05-21 16:20:58 +0000826 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000827 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
828 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
829 // for real ONU's that should have nearly no influence
830 // Note that for real ONU's there is anyway a problematic situation with following sequence:
831 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
832 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
833 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000834 dh.setReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000835
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000836 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000837 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000838 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000839 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000840 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000841 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000842 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000843 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300844}
845
dbainbri4d3a0dc2020-12-02 00:33:42 +0000846func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
847 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000848
dbainbri4d3a0dc2020-12-02 00:33:42 +0000849 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000850 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000851 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000852 return
853 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000854 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000855 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000856 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000857 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000858 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000859 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700860 dh.stopReconciling(ctx, false)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000861 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000862 }
Himani Chawla4d908332020-08-31 12:30:20 +0530863 var onuIndication oop.OnuIndication
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000864 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000865 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
866 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
867 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
868 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000869 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000870 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000871}
872
dbainbri4d3a0dc2020-12-02 00:33:42 +0000873func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
874 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000875
dbainbri4d3a0dc2020-12-02 00:33:42 +0000876 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000877 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000878 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000879 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700880 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000881 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000882 return
883 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000884 dh.pOnuTP.lockTpProcMutex()
885 defer dh.pOnuTP.unlockTpProcMutex()
886
mpagenko2dc896e2021-08-02 12:03:59 +0000887 pDevEntry.mutexPersOnuConfig.RLock()
888 persMutexLock := true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000889 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko2dc896e2021-08-02 12:03:59 +0000890 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000891 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000892 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000893 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700894 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000895 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000896 return
897 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000898 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700899 techProfsFound := false
900 techProfInstLoadFailed := false
901outerLoop:
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000902 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000903 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
904 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000905 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000906 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000907 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000908 }
mpagenko2dc896e2021-08-02 12:03:59 +0000909 //release mutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
910 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
911 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
912 pDevEntry.mutexPersOnuConfig.RUnlock()
913 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700914 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800915 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700916 // Request the TpInstance again from the openolt adapter in case of reconcile
917 iaTechTpInst, err := dh.AdapterProxy.TechProfileInstanceRequest(ctx, uniData.PersTpPathMap[tpID],
918 dh.device.ParentPortNo, dh.device.ProxyAddress.OnuId, uint32(uniData.PersUniID),
919 dh.pOpenOnuAc.config.Topic, dh.ProxyAddressType,
920 dh.parentID, dh.ProxyAddressID)
921 if err != nil || iaTechTpInst == nil {
922 logger.Errorw(ctx, "error fetching tp instance",
923 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID, "err": err})
924 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
925 break outerLoop
926 }
927 var tpInst tech_profile.TechProfileInstance
928 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
929 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
930 tpInst = *techTpInst.TpInstance
mpagenko2dc896e2021-08-02 12:03:59 +0000931 logger.Debugw(ctx, "received-tp-instance-successfully-after-reconcile", log.Fields{
932 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700933 default: // do not support epon or other tech
mpagenko2dc896e2021-08-02 12:03:59 +0000934 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
935 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700936 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
937 break outerLoop
938 }
939
Girish Gowdra041dcb32020-11-16 16:54:30 -0800940 // deadline context to ensure completion of background routines waited for
941 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
942 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000943 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000944
Girish Gowdra041dcb32020-11-16 16:54:30 -0800945 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
946 var wg sync.WaitGroup
947 wg.Add(1) // for the 1 go routine to finish
Girish Gowdra50e56422021-06-01 16:46:04 -0700948 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000949 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800950 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000951 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700952 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
953 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800954 }
mpagenko2dc896e2021-08-02 12:03:59 +0000955 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000956 if len(uniData.PersFlowParams) != 0 {
957 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000958 }
mpagenko2dc896e2021-08-02 12:03:59 +0000959 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
960 persMutexLock = true
961 } // for all UNI entries from sOnuPersistentData
962 if persMutexLock { // if loop was left with mutexPersOnuConfig still set
963 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000964 }
mpagenko2dc896e2021-08-02 12:03:59 +0000965
966 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
967 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
968}
969
970func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
971 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
972 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000973 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
974 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000975 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700976 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000977 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000978 return
979 }
mpagenko2dc896e2021-08-02 12:03:59 +0000980 if abTechProfInstLoadFailed {
Girish Gowdra50e56422021-06-01 16:46:04 -0700981 dh.setDeviceReason(drTechProfileConfigDownloadFailed)
982 dh.stopReconciling(ctx, false)
983 return
984 } else if dh.isSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000985 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
986 }
mpagenko2dc896e2021-08-02 12:03:59 +0000987 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000988 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
989 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000990 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700991 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000992 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000993 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000994}
995
dbainbri4d3a0dc2020-12-02 00:33:42 +0000996func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
997 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000998
dbainbri4d3a0dc2020-12-02 00:33:42 +0000999 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001000 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001001 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001002 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001003 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001004 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001005 return
1006 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001007
mpagenko2dc896e2021-08-02 12:03:59 +00001008 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001009 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko2dc896e2021-08-02 12:03:59 +00001010 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001011 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001012 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001013 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001014 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001015 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001016 return
1017 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001018 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001019 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001020 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1021 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001022 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001023 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001024 continue
1025 }
1026 if len(uniData.PersTpPathMap) == 0 {
1027 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
1028 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001029 // It doesn't make sense to configure any flows if no TPs are available
1030 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001031 }
mpagenko2dc896e2021-08-02 12:03:59 +00001032 //release mutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1033 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
1034 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1035 pDevEntry.mutexPersOnuConfig.RUnlock()
1036
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001037 var uniPort *onuUniPort
1038 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +00001039 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001040 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001041 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
1042 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001043 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001044 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001045 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001046 return
1047 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001048 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001049 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001050 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001051 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001052 for _, flowData := range uniData.PersFlowParams {
mpagenko2dc896e2021-08-02 12:03:59 +00001053 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1054 "device-id": dh.deviceID, "uni-id": uniData.PersUniID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001055 // If this is the last flow for the device we need to announce it the waiting
1056 // chReconcilingFlowsFinished channel
1057 if flowsProcessed == len(uniData.PersFlowParams)-1 {
1058 lastFlowToReconcile = true
1059 }
mpagenko01e726e2020-10-23 09:45:29 +00001060 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenko7d14de12021-07-27 08:31:56 +00001061 dh.lockVlanConfig.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001062 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001063 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +00001064 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +03001065 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001066 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001067 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001068 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001069 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00001070 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +03001071 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001072 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001073 }
1074 }
mpagenko7d14de12021-07-27 08:31:56 +00001075 dh.lockVlanConfig.Unlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001076 flowsProcessed++
mpagenko2dc896e2021-08-02 12:03:59 +00001077 } //for all flows of this UNI
1078 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
1079 "device-id": dh.deviceID, "uni-id": uniData.PersUniID, "flowsProcessed": flowsProcessed,
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001080 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
1081 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001082 // this can't be used as global finished reconciling flag because
1083 // assumes is getting called before the state machines for the last flow is completed,
1084 // while this is not guaranteed.
1085 //dh.setReconcilingFlows(false)
mpagenko2dc896e2021-08-02 12:03:59 +00001086 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
1087 } // for all UNI entries from sOnuPersistentData
1088 pDevEntry.mutexPersOnuConfig.RUnlock()
1089
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001090 if !flowsFound {
1091 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
1092 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001093 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001094 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001095 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001096 return
1097 }
1098 if dh.isSkipOnuConfigReconciling() {
1099 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001100 }
1101}
1102
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001103func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
1104 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001105 dh.stopReconciling(ctx, true)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001106}
1107
dbainbri4d3a0dc2020-12-02 00:33:42 +00001108func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
1109 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001110
dbainbri4d3a0dc2020-12-02 00:33:42 +00001111 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001112 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001113 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +00001114 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001115 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001116 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001117
1118 // deadline context to ensure completion of background routines waited for
1119 //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 +05301120 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001121 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001122
1123 pDevEntry.resetKvProcessingErrorIndication()
1124
1125 var wg sync.WaitGroup
1126 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001127 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1128 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001129
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001130 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001131 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001132}
1133
mpagenko15ff4a52021-03-02 10:09:20 +00001134//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1135// before this change here return like this was used:
1136// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1137//was and is called in background - error return does not make sense
1138func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1139 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1140 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001141 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001142 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001143 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001144 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301145 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001146 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001147 return
Himani Chawla4d908332020-08-31 12:30:20 +05301148 }
mpagenko01e726e2020-10-23 09:45:29 +00001149
1150 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001151 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001152
dbainbri4d3a0dc2020-12-02 00:33:42 +00001153 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001154 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001155 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001156 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001157 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001158 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001159 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001160 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001161 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001162 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001163 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001164 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001165 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1166 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1167 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1168 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001169}
1170
mpagenkoc8bba412021-01-15 15:38:44 +00001171//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001172// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001173func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1174 apDownloadManager *adapterDownloadManager) error {
1175 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001176 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001177
1178 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001179 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1180 if pDevEntry == nil {
1181 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1182 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1183 }
1184
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001185 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001186 var inactiveImageID uint16
1187 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1188 dh.lockUpgradeFsm.Lock()
1189 defer dh.lockUpgradeFsm.Unlock()
1190 if dh.pOnuUpradeFsm == nil {
1191 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1192 if err == nil {
1193 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1194 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1195 "device-id": dh.deviceID, "error": err})
1196 }
1197 } else {
1198 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001199 "device-id": dh.deviceID, "error": err})
1200 }
mpagenko15ff4a52021-03-02 10:09:20 +00001201 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1202 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
mpagenko38662d02021-08-11 09:45:19 +00001203 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1204 //no effort spent anymore for the old API to automatically cancel and restart the download
1205 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001206 }
mpagenko15ff4a52021-03-02 10:09:20 +00001207 } else {
1208 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1209 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001210 }
1211 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001212 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1213 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001214 }
1215 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001216}
1217
mpagenkoc26d4c02021-05-06 14:27:57 +00001218//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1219// after the OnuImage has been downloaded to the adapter, called in background
1220func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
1221 apDownloadManager *fileDownloadManager, aImageIdentifier string) {
1222
1223 var err error
1224 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1225 if pDevEntry == nil {
1226 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1227 return
1228 }
1229
1230 var inactiveImageID uint16
1231 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1232 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
1233 "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001234
1235 dh.lockUpgradeFsm.RLock()
1236 lopOnuUpradeFsm := dh.pOnuUpradeFsm
1237 //lockUpgradeFsm must be release before cancellation as this may implicitly request removeOnuUpgradeFsm()
1238 dh.lockUpgradeFsm.RUnlock()
1239 if lopOnuUpradeFsm != nil {
1240 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1241 // abort the current processing, running upgrades are always aborted by newer request
1242 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.deviceID})
1243 //flush the remove upgradeFsmChan channel
1244 select {
1245 case <-dh.upgradeFsmChan:
1246 logger.Debug(ctx, "flushed-upgrade-fsm-channel")
1247 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001248 }
mpagenko38662d02021-08-11 09:45:19 +00001249 lopOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1250 select {
1251 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
1252 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.deviceID})
1253 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1254 return
1255 case <-dh.upgradeFsmChan:
1256 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.deviceID})
1257 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001258 }
mpagenko38662d02021-08-11 09:45:19 +00001259
1260 //here it can be assumed that no running upgrade processing exists (anymore)
1261 //OmciOnuSwUpgradeDone could be used to create some Kafka event with information on upgrade completion,
1262 // but none yet defined
1263 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1264 if err == nil {
1265 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1266 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1267 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
mpagenkoc26d4c02021-05-06 14:27:57 +00001268 "device-id": dh.deviceID, "error": err})
1269 return
1270 }
mpagenko38662d02021-08-11 09:45:19 +00001271 } else {
1272 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1273 "device-id": dh.deviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001274 }
1275 return
1276 }
1277 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1278 "device-id": dh.deviceID, "error": err})
1279}
1280
1281//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001282func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1283 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001284 var err error
1285 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1286 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1287 // 2.) activation of the inactive image
1288
1289 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1290 if pDevEntry == nil {
1291 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001292 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001293 }
1294 dh.lockUpgradeFsm.RLock()
1295 if dh.pOnuUpradeFsm != nil {
1296 dh.lockUpgradeFsm.RUnlock()
1297 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1298 dh.deviceID, dh.deviceID)
1299 if getErr != nil || onuVolthaDevice == nil {
1300 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 +00001301 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001302 }
1303 // use the OnuVendor identification from this device for the internal unique name
1304 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001305 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001306 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001307 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001308 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1309 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001310 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001311 }
mpagenko183647c2021-06-08 15:25:04 +00001312 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1313 "device-id": dh.deviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001314 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001315 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001316 } //else
1317 dh.lockUpgradeFsm.RUnlock()
1318
1319 // 2.) check if requested image-version equals the inactive one and start its activation
1320 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1321 var inactiveImageID uint16
1322 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1323 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1324 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
mpagenko183647c2021-06-08 15:25:04 +00001325 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001326 }
1327 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1328 if err == nil {
1329 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1330 inactiveImageID, aCommitRequest); err != nil {
1331 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1332 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001333 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001334 }
1335 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1336 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001337 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001338 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001339 } //else
1340 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1341 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001342 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001343}
1344
1345//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001346func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1347 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001348 var err error
1349 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1350 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1351 // 2.) commitment of the active image
1352
1353 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1354 if pDevEntry == nil {
1355 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001356 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001357 }
1358 dh.lockUpgradeFsm.RLock()
1359 if dh.pOnuUpradeFsm != nil {
1360 dh.lockUpgradeFsm.RUnlock()
1361 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1362 dh.deviceID, dh.deviceID)
1363 if getErr != nil || onuVolthaDevice == nil {
1364 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 +00001365 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001366 }
1367 // use the OnuVendor identification from this device for the internal unique name
1368 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001369 // 1.) check a started upgrade process and relay the commitment request to it
1370 // the running upgrade may be based either on the imageIdentifier (started from download)
1371 // or on the imageVersion (started from pure activation)
1372 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1373 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001374 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1375 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001376 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001377 }
mpagenko183647c2021-06-08 15:25:04 +00001378 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1379 "device-id": dh.deviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001380 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001381 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001382 } //else
1383 dh.lockUpgradeFsm.RUnlock()
1384
mpagenko183647c2021-06-08 15:25:04 +00001385 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001386 var activeImageID uint16
1387 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1388 logger.Errorw(ctx, "get active image failed", log.Fields{
1389 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
mpagenko183647c2021-06-08 15:25:04 +00001390 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001391 }
1392 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1393 if err == nil {
1394 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1395 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1396 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001397 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001398 }
1399 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1400 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001401 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001402 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001403 } //else
1404 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1405 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001406 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001407}
1408
mpagenkoaa3afe92021-05-21 16:20:58 +00001409func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001410 aVersion string) *voltha.ImageState {
1411 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001412 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001413 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001414 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001415 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1416 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1417 if aVersion == dh.pLastUpgradeImageState.Version {
1418 pImageState = dh.pLastUpgradeImageState
1419 } else { //state request for an image version different from last processed image version
1420 pImageState = &voltha.ImageState{
1421 Version: aVersion,
1422 //we cannot state something concerning this version
1423 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1424 Reason: voltha.ImageState_NO_ERROR,
1425 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1426 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001427 }
1428 }
mpagenko38662d02021-08-11 09:45:19 +00001429 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001430}
1431
1432func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1433 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1434 pDeviceImageState.DeviceId = dh.deviceID
mpagenko7455fd42021-06-10 16:25:55 +00001435 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001436 dh.lockUpgradeFsm.RLock()
1437 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001438 if aVersion == dh.pOnuUpradeFsm.GetImageVersion(ctx) {
1439 // so then we cancel the upgrade operation
1440 // but before we still request the actual ImageState (which should not change with the cancellation)
1441 pDeviceImageState.ImageState.ImageState = dh.pOnuUpradeFsm.GetSpecificImageState(ctx)
1442 dh.lockUpgradeFsm.RUnlock()
1443 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
1444 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1445 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1446 } else { //nothing to cancel, states unknown
1447 dh.lockUpgradeFsm.RUnlock()
1448 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1449 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1450 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1451 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001452 } else {
mpagenko38662d02021-08-11 09:45:19 +00001453 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1454 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1455 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1456 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1457 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1458 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001459 dh.lockUpgradeFsm.RUnlock()
1460 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1461 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001462 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1463 //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 +00001464 }
1465}
1466
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001467func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1468
1469 var onuImageStatus *OnuImageStatus
1470
1471 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1472 if pDevEntry != nil {
1473 onuImageStatus = NewOnuImageStatus(pDevEntry)
1474 pDevEntry.mutexOnuImageStatus.Lock()
1475 pDevEntry.pOnuImageStatus = onuImageStatus
1476 pDevEntry.mutexOnuImageStatus.Unlock()
1477
1478 } else {
1479 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1480 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1481 }
1482 images, err := onuImageStatus.getOnuImageStatus(ctx)
1483 pDevEntry.mutexOnuImageStatus.Lock()
1484 pDevEntry.pOnuImageStatus = nil
1485 pDevEntry.mutexOnuImageStatus.Unlock()
1486 return images, err
1487}
1488
Himani Chawla6d2ae152020-09-02 13:11:20 +05301489// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001490// #####################################################################################
1491
1492// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301493// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001494
dbainbri4d3a0dc2020-12-02 00:33:42 +00001495func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1496 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 +00001497}
1498
1499// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001500func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001501
dbainbri4d3a0dc2020-12-02 00:33:42 +00001502 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001503 var err error
1504
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001505 // populate what we know. rest comes later after mib sync
1506 dh.device.Root = false
1507 dh.device.Vendor = "OpenONU"
1508 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001509 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001510 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001511
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001512 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001513
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001514 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001515 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1516 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301517 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001518 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001519 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001520 log.Fields{"device-id": dh.deviceID})
1521 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001522
Himani Chawla4d908332020-08-31 12:30:20 +05301523 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001524 dh.ponPortNumber = dh.device.ParentPortNo
1525
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001526 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1527 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1528 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001529 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001530 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301531 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001532
1533 /*
1534 self._pon = PonPort.create(self, self._pon_port_number)
1535 self._pon.add_peer(self.parent_id, self._pon_port_number)
1536 self.logger.debug('adding-pon-port-to-agent',
1537 type=self._pon.get_port().type,
1538 admin_state=self._pon.get_port().admin_state,
1539 oper_status=self._pon.get_port().oper_status,
1540 )
1541 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001542 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001543 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001544 var ponPortNo uint32 = 1
1545 if dh.ponPortNumber != 0 {
1546 ponPortNo = dh.ponPortNumber
1547 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001548
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001549 pPonPort := &voltha.Port{
1550 PortNo: ponPortNo,
1551 Label: fmt.Sprintf("pon-%d", ponPortNo),
1552 Type: voltha.Port_PON_ONU,
1553 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301554 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001555 PortNo: ponPortNo}}, // Peer port is parent's port number
1556 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001557 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1558 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001559 e.Cancel(err)
1560 return
1561 }
1562 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001563 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001564 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001565 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001566}
1567
1568// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001569func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001570
dbainbri4d3a0dc2020-12-02 00:33:42 +00001571 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001572 var err error
1573 /*
1574 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1575 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1576 return nil
1577 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001578 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1579 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001580 e.Cancel(err)
1581 return
1582 }
1583
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001584 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001585 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001586 // reconcilement will be continued after mib download is done
1587 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001588
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001589 /*
1590 ############################################################################
1591 # Setup Alarm handler
1592 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1593 device.serial_number)
1594 ############################################################################
1595 # Setup PM configuration for this device
1596 # Pass in ONU specific options
1597 kwargs = {
1598 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1599 'heartbeat': self.heartbeat,
1600 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1601 }
1602 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1603 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1604 self.logical_device_id, device.serial_number,
1605 grouped=True, freq_override=False, **kwargs)
1606 pm_config = self._pm_metrics.make_proto()
1607 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1608 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1609 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1610
1611 # Note, ONU ID and UNI intf set in add_uni_port method
1612 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1613 ani_ports=[self._pon])
1614
1615 # Code to Run OMCI Test Action
1616 kwargs_omci_test_action = {
1617 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1618 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1619 }
1620 serial_number = device.serial_number
1621 self._test_request = OmciTestRequest(self.core_proxy,
1622 self.omci_agent, self.device_id,
1623 AniG, serial_number,
1624 self.logical_device_id,
1625 exclusive=False,
1626 **kwargs_omci_test_action)
1627
1628 self.enabled = True
1629 else:
1630 self.logger.info('onu-already-activated')
1631 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001632
dbainbri4d3a0dc2020-12-02 00:33:42 +00001633 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001634}
1635
1636// doStateConnected get the device info and update to voltha core
1637// for comparison of the original method (not that easy to uncomment): compare here:
1638// voltha-openolt-adapter/adaptercore/device_handler.go
1639// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001640func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001641
dbainbri4d3a0dc2020-12-02 00:33:42 +00001642 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301643 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001644 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001645 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001646}
1647
1648// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001649func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001650
dbainbri4d3a0dc2020-12-02 00:33:42 +00001651 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301652 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001653 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001655
1656 /*
1657 // Synchronous call to update device state - this method is run in its own go routine
1658 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1659 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001660 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 +00001661 return err
1662 }
1663 return nil
1664 */
1665}
1666
1667// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001668func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001669
dbainbri4d3a0dc2020-12-02 00:33:42 +00001670 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001671 var err error
1672
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001673 device := dh.device
1674 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001675 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001676 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001677 e.Cancel(err)
1678 return
1679 }
1680
1681 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001682 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001683 /*
1684 // Update the all ports state on that device to disable
1685 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001686 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001687 return er
1688 }
1689
1690 //Update the device oper state and connection status
1691 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1692 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1693 dh.device = cloned
1694
1695 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001696 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001697 return er
1698 }
1699
1700 //get the child device for the parent device
1701 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1702 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001703 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001704 return err
1705 }
1706 for _, onuDevice := range onuDevices.Items {
1707
1708 // Update onu state as down in onu adapter
1709 onuInd := oop.OnuIndication{}
1710 onuInd.OperState = "down"
1711 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1712 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1713 if er != nil {
1714 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001715 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001716 //Do not return here and continue to process other ONUs
1717 }
1718 }
1719 // * Discovered ONUs entries need to be cleared , since after OLT
1720 // is up, it starts sending discovery indications again* /
1721 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001722 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001723 return nil
1724 */
Himani Chawla4d908332020-08-31 12:30:20 +05301725 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001726 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001727 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001728}
1729
Himani Chawla6d2ae152020-09-02 13:11:20 +05301730// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001731// #################################################################################
1732
1733// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301734// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001735
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001736//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001737func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001738 dh.lockDevice.RLock()
1739 pOnuDeviceEntry := dh.pOnuOmciDevice
1740 if aWait && pOnuDeviceEntry == nil {
1741 //keep the read sema short to allow for subsequent write
1742 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001743 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001744 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1745 // so it might be needed to wait here for that event with some timeout
1746 select {
1747 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001748 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001749 return nil
1750 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001751 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001752 // if written now, we can return the written value without sema
1753 return dh.pOnuOmciDevice
1754 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001755 }
mpagenko3af1f032020-06-10 08:53:41 +00001756 dh.lockDevice.RUnlock()
1757 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001758}
1759
Himani Chawla6d2ae152020-09-02 13:11:20 +05301760//setOnuDeviceEntry sets the ONU device entry within the handler
1761func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001762 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001763 dh.lockDevice.Lock()
1764 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001765 dh.pOnuOmciDevice = apDeviceEntry
1766 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001767 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301768 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001769 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001770}
1771
Himani Chawla6d2ae152020-09-02 13:11:20 +05301772//addOnuDeviceEntry creates a new ONU device or returns the existing
1773func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001774 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001775
dbainbri4d3a0dc2020-12-02 00:33:42 +00001776 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001777 if deviceEntry == nil {
1778 /* costum_me_map in python code seems always to be None,
1779 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1780 /* also no 'clock' argument - usage open ...*/
1781 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001782 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001783 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001784 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301785 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001786 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001787 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001788 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001789 // fire deviceEntry ready event to spread to possibly waiting processing
1790 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001791 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001792 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001793 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001794 }
1795 // might be updated with some error handling !!!
1796 return nil
1797}
1798
dbainbri4d3a0dc2020-12-02 00:33:42 +00001799func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1800 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001801 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1802
1803 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001804
dbainbri4d3a0dc2020-12-02 00:33:42 +00001805 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001806 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001807 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001808 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1809 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001810 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001811 if err := dh.storePersistentData(ctx); err != nil {
1812 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001813 log.Fields{"device-id": dh.deviceID, "err": err})
1814 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001815 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001816 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001817 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001818 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1819 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001820 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001821 }
1822 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001823 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001824 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001825
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001826 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001827 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001828 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001829 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 +00001830 log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001831 dh.stopReconciling(ctx, true)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001832 } else {
1833 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001834 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001835 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001836 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1837 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1838 // 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 +00001839 // 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 +00001840 // so let's just try to keep it simple ...
1841 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001842 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001843 if err != nil || device == nil {
1844 //TODO: needs to handle error scenarios
1845 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1846 return errors.New("Voltha Device not found")
1847 }
1848 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001849
dbainbri4d3a0dc2020-12-02 00:33:42 +00001850 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001851 return err
mpagenko3af1f032020-06-10 08:53:41 +00001852 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001853
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001854 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001855
1856 /* this might be a good time for Omci Verify message? */
1857 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001858 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001859 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001860 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001861 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001862
1863 /* give the handler some time here to wait for the OMCi verification result
1864 after Timeout start and try MibUpload FSM anyway
1865 (to prevent stopping on just not supported OMCI verification from ONU) */
1866 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001867 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001868 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001869 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001870 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001871 }
1872
1873 /* In py code it looks earlier (on activate ..)
1874 # Code to Run OMCI Test Action
1875 kwargs_omci_test_action = {
1876 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1877 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1878 }
1879 serial_number = device.serial_number
1880 self._test_request = OmciTestRequest(self.core_proxy,
1881 self.omci_agent, self.device_id,
1882 AniG, serial_number,
1883 self.logical_device_id,
1884 exclusive=False,
1885 **kwargs_omci_test_action)
1886 ...
1887 # Start test requests after a brief pause
1888 if not self._test_request_started:
1889 self._test_request_started = True
1890 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1891 reactor.callLater(tststart, self._test_request.start_collector)
1892
1893 */
1894 /* which is then: in omci_test_request.py : */
1895 /*
1896 def start_collector(self, callback=None):
1897 """
1898 Start the collection loop for an adapter if the frequency > 0
1899
1900 :param callback: (callable) Function to call to collect PM data
1901 """
1902 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1903 if callback is None:
1904 callback = self.perform_test_omci
1905
1906 if self.lc is None:
1907 self.lc = LoopingCall(callback)
1908
1909 if self.default_freq > 0:
1910 self.lc.start(interval=self.default_freq / 10)
1911
1912 def perform_test_omci(self):
1913 """
1914 Perform the initial test request
1915 """
1916 ani_g_entities = self._device.configuration.ani_g_entities
1917 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1918 is not None else None
1919 self._entity_id = ani_g_entities_ids[0]
1920 self.logger.info('perform-test', entity_class=self._entity_class,
1921 entity_id=self._entity_id)
1922 try:
1923 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1924 result = yield self._device.omci_cc.send(frame)
1925 if not result.fields['omci_message'].fields['success_code']:
1926 self.logger.info('Self-Test Submitted Successfully',
1927 code=result.fields[
1928 'omci_message'].fields['success_code'])
1929 else:
1930 raise TestFailure('Test Failure: {}'.format(
1931 result.fields['omci_message'].fields['success_code']))
1932 except TimeoutError as e:
1933 self.deferred.errback(failure.Failure(e))
1934
1935 except Exception as e:
1936 self.logger.exception('perform-test-Error', e=e,
1937 class_id=self._entity_class,
1938 entity_id=self._entity_id)
1939 self.deferred.errback(failure.Failure(e))
1940
1941 */
1942
1943 // PM related heartbeat??? !!!TODO....
1944 //self._heartbeat.enabled = True
1945
mpagenko1cc3cb42020-07-27 15:24:38 +00001946 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1947 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1948 * 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 +05301949 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001950 */
1951 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001952 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001953 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001954 if pMibUlFsm.Is(ulStDisabled) {
1955 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001956 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 +00001957 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301958 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301960 //Determine ONU status and start/re-start MIB Synchronization tasks
1961 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001962 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301963 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001964 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 +00001965 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001966 }
Himani Chawla4d908332020-08-31 12:30:20 +05301967 } else {
1968 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001969 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 +00001970 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301971 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001972 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001973 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001974 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001975 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001976 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001977 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001978 }
1979 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001980 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001981 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001982 }
1983 return nil
1984}
1985
dbainbri4d3a0dc2020-12-02 00:33:42 +00001986func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001987 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001988 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001989 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001990 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001991
mpagenko900ee4b2020-10-12 11:56:34 +00001992 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1993 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1994 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001995 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001996 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001997 log.Fields{"device-id": dh.deviceID, "error": err})
1998 // abort: system behavior is just unstable ...
1999 return err
2000 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002001 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002002 _ = 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 +00002003
2004 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
2005 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
2006 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00002007 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002008 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002009 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002010 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002011 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002012 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002013
2014 //TODO!!! remove existing traffic profiles
2015 /* from py code, if TP's exist, remove them - not yet implemented
2016 self._tp = dict()
2017 # Let TP download happen again
2018 for uni_id in self._tp_service_specific_task:
2019 self._tp_service_specific_task[uni_id].clear()
2020 for uni_id in self._tech_profile_download_done:
2021 self._tech_profile_download_done[uni_id].clear()
2022 */
2023
dbainbri4d3a0dc2020-12-02 00:33:42 +00002024 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002025
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002026 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002027
dbainbri4d3a0dc2020-12-02 00:33:42 +00002028 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002029 // abort: system behavior is just unstable ...
2030 return err
2031 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002032 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002033 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002034 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00002035 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002036 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002037 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00002038 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002039 // abort: system behavior is just unstable ...
2040 return err
2041 }
2042 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002043 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002044 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002045 return nil
2046}
2047
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002048func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002049 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2050 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2051 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2052 // and using the stop/reset event should never harm
2053
dbainbri4d3a0dc2020-12-02 00:33:42 +00002054 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002055 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002056 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002057 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2058 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002059 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002060 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002061 }
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002062 pDevEntry.mutexOnuImageStatus.RLock()
2063 if pDevEntry.pOnuImageStatus != nil {
2064 pDevEntry.pOnuImageStatus.CancelProcessing(ctx)
2065 }
2066 pDevEntry.mutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002067
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002068 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002069 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002070 }
2071 //MibDownload may run
2072 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2073 if pMibDlFsm != nil {
2074 _ = pMibDlFsm.Event(dlEvReset)
2075 }
2076 //port lock/unlock FSM's may be active
2077 if dh.pUnlockStateFsm != nil {
2078 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2079 }
2080 if dh.pLockStateFsm != nil {
2081 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2082 }
2083 //techProfile related PonAniConfigFsm FSM may be active
2084 if dh.pOnuTP != nil {
2085 // should always be the case here
2086 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
2087 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08002088 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00002089 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002090 }
mpagenko900ee4b2020-10-12 11:56:34 +00002091 }
2092 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002093 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002094 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00002095 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
2096 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002097 dh.lockVlanConfig.RUnlock()
2098 //reset of all Fsm is always accompanied by global persistency data removal
2099 // no need to remove specific data
2100 pVlanFilterFsm.RequestClearPersistency(false)
2101 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002102 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002103 } else {
2104 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002105 }
2106 }
2107 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002108 if dh.getCollectorIsRunning() {
2109 // Stop collector routine
2110 dh.stopCollector <- true
2111 }
Himani Chawla1472c682021-03-17 17:11:14 +05302112 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302113 dh.stopAlarmManager <- true
2114 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002115 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
2116 dh.pSelfTestHdlr.stopSelfTestModule <- true
2117 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302118
mpagenko80622a52021-02-09 16:53:23 +00002119 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00002120 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002121 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002122 lopOnuUpradeFsm := dh.pOnuUpradeFsm
2123 //lockUpgradeFsm must be release before cancellation as this may implicitly request removeOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002124 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002125 if lopOnuUpradeFsm != nil {
2126 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2127 }
mpagenko80622a52021-02-09 16:53:23 +00002128
mpagenko7d6bb022021-03-11 15:07:55 +00002129 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002130 return nil
2131}
2132
dbainbri4d3a0dc2020-12-02 00:33:42 +00002133func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2134 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 +05302135
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002136 // store persistent data collected during MIB upload processing
2137 if err := dh.storePersistentData(ctx); err != nil {
2138 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2139 log.Fields{"device-id": dh.deviceID, "err": err})
2140 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002141 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002142 dh.addAllUniPorts(ctx)
2143
mpagenkoa40e99a2020-11-17 13:50:39 +00002144 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2145 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2146 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2147 * disable/enable toggling here to allow traffic
2148 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2149 * like the py comment says:
2150 * # start by locking all the unis till mib sync and initial mib is downloaded
2151 * # this way we can capture the port down/up events when we are ready
2152 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302153
mpagenkoa40e99a2020-11-17 13:50:39 +00002154 // Init Uni Ports to Admin locked state
2155 // *** should generate UniLockStateDone event *****
2156 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002157 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002158 } else { //LockStateFSM already init
2159 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002160 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002161 }
2162}
2163
dbainbri4d3a0dc2020-12-02 00:33:42 +00002164func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2165 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302166 /* Mib download procedure -
2167 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2168 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002169 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002170 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002171 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002172 return
2173 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302174 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2175 if pMibDlFsm != nil {
2176 if pMibDlFsm.Is(dlStDisabled) {
2177 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002178 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 +05302179 // maybe try a FSM reset and then again ... - TODO!!!
2180 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002181 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302182 // maybe use more specific states here for the specific download steps ...
2183 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002184 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302185 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002186 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302187 //Begin MIB data download (running autonomously)
2188 }
2189 }
2190 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002191 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002192 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302193 // maybe try a FSM reset and then again ... - TODO!!!
2194 }
2195 /***** Mib download started */
2196 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002197 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302198 }
2199}
2200
dbainbri4d3a0dc2020-12-02 00:33:42 +00002201func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2202 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302203 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002204 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002205 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002206 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002207 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2208 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2209 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2210 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002211 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302212 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
2213 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002214 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302215 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002216 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302217 }
2218 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002219 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302220 log.Fields{"device-id": dh.deviceID})
2221 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002222 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002223
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002224 if !dh.getCollectorIsRunning() {
2225 // Start PM collector routine
2226 go dh.startCollector(ctx)
2227 }
2228 if !dh.getAlarmManagerIsRunning(ctx) {
2229 go dh.startAlarmManager(ctx)
2230 }
2231
Girish Gowdrae0140f02021-02-02 16:55:09 -08002232 // Initialize classical L2 PM Interval Counters
2233 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2234 // There is no way we should be landing here, but if we do then
2235 // there is nothing much we can do about this other than log error
2236 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2237 }
2238
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002239 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002240
2241 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2242 if pDevEntry == nil {
2243 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2244 return
2245 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002246 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002247 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002248 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002249 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2250 log.Fields{"device-id": dh.deviceID})
2251 go dh.reconcileDeviceTechProf(ctx)
2252 // reconcilement will be continued after ani config is done
2253 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002254 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002255 // *** should generate UniUnlockStateDone event *****
2256 if dh.pUnlockStateFsm == nil {
2257 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2258 } else { //UnlockStateFSM already init
2259 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2260 dh.runUniLockFsm(ctx, false)
2261 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302262 }
2263}
2264
dbainbri4d3a0dc2020-12-02 00:33:42 +00002265func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2266 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302267
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002268 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002269 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002270 raisedTs := time.Now().Unix()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002271 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2272 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002273 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002274 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002275 return
2276 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002277 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002278 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002279 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002280 if err := dh.storePersistentData(ctx); err != nil {
2281 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002282 log.Fields{"device-id": dh.deviceID, "err": err})
2283 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302284 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002285 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 +05302286 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002287 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002288 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302289 }
2290}
2291
dbainbri4d3a0dc2020-12-02 00:33:42 +00002292func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2293 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002294 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002295 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00002296 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
2297 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002298 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002299 }
2300
dbainbri4d3a0dc2020-12-02 00:33:42 +00002301 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002302 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002303 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002304
2305 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002306 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002307
dbainbri4d3a0dc2020-12-02 00:33:42 +00002308 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002309 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002310 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002311 return
2312 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002313 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002314 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002315 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002316 if err := dh.storePersistentData(ctx); err != nil {
2317 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002318 log.Fields{"device-id": dh.deviceID, "err": err})
2319 }
mpagenko900ee4b2020-10-12 11:56:34 +00002320}
2321
dbainbri4d3a0dc2020-12-02 00:33:42 +00002322func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2323 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002324 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002325 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002326 voltha.OperStatus_ACTIVE); err != nil {
2327 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002328 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002329 }
2330
dbainbri4d3a0dc2020-12-02 00:33:42 +00002331 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002332 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002333 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002334 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002335
2336 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002337 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002338
dbainbri4d3a0dc2020-12-02 00:33:42 +00002339 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002340 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002341 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002342 return
2343 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002344 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002345 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002346 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002347 if err := dh.storePersistentData(ctx); err != nil {
2348 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002349 log.Fields{"device-id": dh.deviceID, "err": err})
2350 }
mpagenko900ee4b2020-10-12 11:56:34 +00002351}
2352
dbainbri4d3a0dc2020-12-02 00:33:42 +00002353func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002354 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002355 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002356 // attention: the device reason update is done based on ONU-UNI-Port related activity
2357 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002358 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002359 // 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 +00002360 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302361 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002362 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002363 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002364 }
2365 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002366 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002367 // attention: the device reason update is done based on ONU-UNI-Port related activity
2368 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002369 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002370 // 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 +00002371 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002372 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002373 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302374}
2375
dbainbri4d3a0dc2020-12-02 00:33:42 +00002376func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2377 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002378 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302379 // attention: the device reason update is done based on ONU-UNI-Port related activity
2380 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302381
mpagenkof1fc3862021-02-16 10:09:52 +00002382 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002383 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002384 // which may be the case from some previous actvity on another UNI Port of the ONU
2385 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002386 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2387 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002388 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002389 }
2390 }
2391 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002392 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002393 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002394 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002395 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302396 }
mpagenkof1fc3862021-02-16 10:09:52 +00002397
2398 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2399 //events that request KvStore write
2400 if err := dh.storePersistentData(ctx); err != nil {
2401 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2402 log.Fields{"device-id": dh.deviceID, "err": err})
2403 }
2404 } else {
2405 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2406 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002407 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302408}
2409
Himani Chawla6d2ae152020-09-02 13:11:20 +05302410//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002411func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302412 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002413 case MibDatabaseSync:
2414 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002415 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002416 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002417 case UniLockStateDone:
2418 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002419 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002420 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002421 case MibDownloadDone:
2422 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002423 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002424 }
2425 case UniUnlockStateDone:
2426 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002427 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002428 }
mpagenko900ee4b2020-10-12 11:56:34 +00002429 case UniEnableStateDone:
2430 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002431 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002432 }
2433 case UniDisableStateDone:
2434 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002435 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002436 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002437 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002438 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002439 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002440 }
mpagenkof1fc3862021-02-16 10:09:52 +00002441 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002442 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002443 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002444 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002445 default:
2446 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002447 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002448 }
2449 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002450}
2451
dbainbri4d3a0dc2020-12-02 00:33:42 +00002452func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002453 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002454 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302455 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002456 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002457 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002458 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302459 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002460 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002461 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002462 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002463 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002464 //store UniPort with the System-PortNumber key
2465 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002466 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002467 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002468 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2469 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002470 } //error logging already within UniPort method
2471 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002472 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002473 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002474 }
2475 }
2476}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002477
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002478func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2479 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2480 if pDevEntry == nil {
2481 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2482 return
2483 }
2484 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2485 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2486 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2487 for _, mgmtEntityID := range pptpInstKeys {
2488 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2489 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2490 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2491 i++
2492 }
2493 } else {
2494 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2495 }
2496 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2497 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2498 for _, mgmtEntityID := range veipInstKeys {
2499 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2500 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2501 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2502 i++
2503 }
2504 } else {
2505 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2506 }
ozgecanetsia124d9732021-09-16 14:31:57 +03002507 if potsInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2508 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2509 for _, mgmtEntityID := range potsInstKeys {
2510 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
2511 "device-id": dh.deviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
2512 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTPPots)
2513 i++
2514 }
2515 } else {
2516 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.deviceID})
2517 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002518 if i == 0 {
2519 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2520 }
2521}
2522
mpagenko3af1f032020-06-10 08:53:41 +00002523// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002524func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002525 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302526 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002527 // with following remark:
2528 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2529 // # load on the core
2530
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002531 // lock_ports(false) as done in py code here is shifted to separate call from device event processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002532
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002533 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002534 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002535 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002536 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302537 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002538 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002539 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002540 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002541 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002542 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002543 }
mpagenko3af1f032020-06-10 08:53:41 +00002544 }
2545 }
2546}
2547
2548// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002549func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002550 // compare enableUniPortStateUpdate() above
2551 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2552 for uniNo, uniPort := range dh.uniEntityMap {
2553 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002554
2555 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002556 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302557 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002558 if !dh.isReconciling() {
2559 //maybe also use getter functions on uniPort - perhaps later ...
2560 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2561 } else {
2562 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2563 }
2564
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002565 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002566 }
2567}
2568
2569// ONU_Active/Inactive announcement on system KAFKA bus
2570// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002571func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002572 var de voltha.DeviceEvent
2573 eventContext := make(map[string]string)
2574 //Populating event context
2575 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002576 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002577 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002578 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302579 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002580 return //TODO with VOL-3045: rw-core is unresponsive: report error and/or perform self-initiated onu-reset?
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002581 }
2582 oltSerialNumber := parentDevice.SerialNumber
2583
2584 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2585 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2586 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302587 eventContext["olt-serial-number"] = oltSerialNumber
2588 eventContext["device-id"] = aDeviceID
2589 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002590 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
2591 if deviceEntry := dh.getOnuDeviceEntry(ctx, false); deviceEntry != nil {
2592 deviceEntry.mutexPersOnuConfig.RLock()
2593 eventContext["equipment-id"] = deviceEntry.sOnuPersistentData.PersEquipmentID
2594 deviceEntry.mutexPersOnuConfig.RUnlock()
2595 eventContext["software-version"] = deviceEntry.getActiveImageVersion(ctx)
2596 deviceEntry.mutexPersOnuConfig.RLock()
2597 eventContext["vendor"] = deviceEntry.sOnuPersistentData.PersVendorID
2598 deviceEntry.mutexPersOnuConfig.RUnlock()
2599 eventContext["inactive-software-version"] = deviceEntry.getInactiveImageVersion(ctx)
2600 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2601 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2602 } else {
2603 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2604 log.Fields{"device-id": aDeviceID})
2605 return
2606 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002607
2608 /* Populating device event body */
2609 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302610 de.ResourceId = aDeviceID
2611 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002612 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2613 de.Description = fmt.Sprintf("%s Event - %s - %s",
2614 cEventObjectType, cOnuActivatedEvent, "Raised")
2615 } else {
2616 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2617 de.Description = fmt.Sprintf("%s Event - %s - %s",
2618 cEventObjectType, cOnuActivatedEvent, "Cleared")
2619 }
2620 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002621 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2622 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302623 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002624 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002625 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302626 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002627}
2628
Himani Chawla4d908332020-08-31 12:30:20 +05302629// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002630func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002631 chLSFsm := make(chan Message, 2048)
2632 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302633 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002634 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002635 sFsmName = "LockStateFSM"
2636 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002637 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002638 sFsmName = "UnLockStateFSM"
2639 }
mpagenko3af1f032020-06-10 08:53:41 +00002640
dbainbri4d3a0dc2020-12-02 00:33:42 +00002641 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002642 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002643 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002644 return
2645 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002646 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002647 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002648 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302649 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002650 dh.pLockStateFsm = pLSFsm
2651 } else {
2652 dh.pUnlockStateFsm = pLSFsm
2653 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002654 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002655 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002656 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002657 }
2658}
2659
2660// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002661func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002662 /* Uni Port lock/unlock procedure -
2663 ***** should run via 'adminDone' state and generate the argument requested event *****
2664 */
2665 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302666 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002667 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2668 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2669 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002670 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302671 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002672 }
2673 } else {
2674 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2675 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2676 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002677 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302678 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002679 }
2680 }
2681 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002682 if pLSStatemachine.Is(uniStDisabled) {
2683 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002684 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002685 // maybe try a FSM reset and then again ... - TODO!!!
2686 } else {
2687 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002688 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002689 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002690 }
2691 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002692 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002693 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002694 // maybe try a FSM reset and then again ... - TODO!!!
2695 }
2696 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002697 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002698 // maybe try a FSM reset and then again ... - TODO!!!
2699 }
2700}
2701
mpagenko80622a52021-02-09 16:53:23 +00002702// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002703func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002704 //in here lockUpgradeFsm is already locked
2705 chUpgradeFsm := make(chan Message, 2048)
2706 var sFsmName = "OnuSwUpgradeFSM"
2707 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002708 if apDevEntry.PDevOmciCC == nil {
2709 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2710 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002711 }
mpagenko15ff4a52021-03-02 10:09:20 +00002712 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002713 sFsmName, chUpgradeFsm)
2714 if dh.pOnuUpradeFsm != nil {
2715 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2716 if pUpgradeStatemachine != nil {
2717 if pUpgradeStatemachine.Is(upgradeStDisabled) {
2718 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2719 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2720 // maybe try a FSM reset and then again ... - TODO!!!
2721 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2722 }
2723 /***** LockStateFSM started */
mpagenko38662d02021-08-11 09:45:19 +00002724 //reset the last stored upgrade states
2725 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_STARTED //already with updated state
2726 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2727 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002728 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2729 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2730 } else {
2731 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2732 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2733 // maybe try a FSM reset and then again ... - TODO!!!
2734 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2735 }
2736 } else {
2737 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2738 // maybe try a FSM reset and then again ... - TODO!!!
2739 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2740 }
2741 } else {
2742 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2743 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2744 }
2745 return nil
2746}
2747
2748// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
mpagenko38662d02021-08-11 09:45:19 +00002749func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002750 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2751 "device-id": dh.deviceID})
2752 dh.lockUpgradeFsm.Lock()
mpagenko80622a52021-02-09 16:53:23 +00002753 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
mpagenko38662d02021-08-11 09:45:19 +00002754 dh.pLastUpgradeImageState = apImageState
2755 dh.lockUpgradeFsm.Unlock()
2756 //signal upgradeFsm removed using non-blocking channel send
2757 select {
2758 case dh.upgradeFsmChan <- struct{}{}:
2759 default:
2760 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
2761 "device-id": dh.deviceID})
2762 }
mpagenko80622a52021-02-09 16:53:23 +00002763}
2764
mpagenko15ff4a52021-03-02 10:09:20 +00002765// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2766func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2767 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2768 if pDevEntry == nil {
2769 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2770 return
2771 }
2772
2773 dh.lockUpgradeFsm.RLock()
2774 defer dh.lockUpgradeFsm.RUnlock()
2775 if dh.pOnuUpradeFsm != nil {
2776 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2777 if pUpgradeStatemachine != nil {
2778 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2779 // (some manual forced commit could do without)
mpagenko1f8e8822021-06-25 14:10:21 +00002780 upgradeState := pUpgradeStatemachine.Current()
2781 if (upgradeState == upgradeStWaitForCommit) ||
2782 (upgradeState == upgradeStRequestingActivate) {
2783 // also include upgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00002784 // 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 +00002785 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00002786 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
2787 if errImg != nil {
2788 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
2789 log.Fields{"device-id": dh.deviceID})
mpagenko38662d02021-08-11 09:45:19 +00002790 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
mpagenko15ff4a52021-03-02 10:09:20 +00002791 return
2792 }
mpagenko1f8e8822021-06-25 14:10:21 +00002793 if activeImageID == dh.pOnuUpradeFsm.inactiveImageMeID {
2794 if (upgradeState == upgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
2795 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
2796 if err := pUpgradeStatemachine.Event(upgradeEvActivationDone); err != nil {
2797 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
2798 return
2799 }
2800 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
2801 "state": upgradeState, "device-id": dh.deviceID})
2802 } else {
2803 //FSM in waitForCommit or (upgradeStRequestingActivate [lost ActivateResp] and commit allowed)
2804 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2805 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2806 return
2807 }
2808 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2809 "state": upgradeState, "device-id": dh.deviceID})
2810 }
2811 } else {
2812 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit/on ActivateResponse, but load did not start with expected image Id",
2813 log.Fields{"device-id": dh.deviceID})
mpagenko38662d02021-08-11 09:45:19 +00002814 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
mpagenko1f8e8822021-06-25 14:10:21 +00002815 return
2816 }
mpagenko15ff4a52021-03-02 10:09:20 +00002817 } else {
2818 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2819 log.Fields{"device-id": dh.deviceID})
mpagenko38662d02021-08-11 09:45:19 +00002820 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
mpagenko15ff4a52021-03-02 10:09:20 +00002821 return
2822 }
mpagenko183647c2021-06-08 15:25:04 +00002823 } else {
2824 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2825 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2826 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2827 if dh.pOnuUpradeFsm.inactiveImageMeID == activeImageID {
2828 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2829 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
mpagenko38662d02021-08-11 09:45:19 +00002830 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00002831 }
2832 }
mpagenko15ff4a52021-03-02 10:09:20 +00002833 }
2834 }
2835 } else {
2836 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2837 }
2838}
2839
Himani Chawla6d2ae152020-09-02 13:11:20 +05302840//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002841func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002842
2843 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002844 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07002845 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00002846 kvbackend := &db.Backend{
2847 Client: dh.pOpenOnuAc.kvClient,
2848 StoreType: dh.pOpenOnuAc.KVStoreType,
2849 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002850 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002851 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2852 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002853
mpagenkoaf801632020-07-03 10:00:42 +00002854 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002855}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002856func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302857 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002858
mpagenkodff5dda2020-08-28 11:52:01 +00002859 for _, field := range flow.GetOfbFields(apFlowItem) {
2860 switch field.Type {
2861 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2862 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002863 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002864 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2865 }
mpagenko01e726e2020-10-23 09:45:29 +00002866 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002867 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2868 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302869 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002870 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302871 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2872 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002873 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2874 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002875 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2876 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302877 return
mpagenkodff5dda2020-08-28 11:52:01 +00002878 }
2879 }
mpagenko01e726e2020-10-23 09:45:29 +00002880 */
mpagenkodff5dda2020-08-28 11:52:01 +00002881 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2882 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302883 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002884 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302885 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002886 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302887 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002888 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002889 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302890 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002891 }
2892 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2893 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302894 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002895 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002896 "PCP": loAddPcp})
2897 }
2898 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2899 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002900 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002901 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2902 }
2903 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2904 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002905 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002906 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2907 }
2908 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2909 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002910 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002911 "IPv4-DST": field.GetIpv4Dst()})
2912 }
2913 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2914 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002915 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002916 "IPv4-SRC": field.GetIpv4Src()})
2917 }
2918 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2919 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002920 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002921 "Metadata": field.GetTableMetadata()})
2922 }
2923 /*
2924 default:
2925 {
2926 //all other entires ignored
2927 }
2928 */
2929 }
2930 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302931}
mpagenkodff5dda2020-08-28 11:52:01 +00002932
dbainbri4d3a0dc2020-12-02 00:33:42 +00002933func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002934 for _, action := range flow.GetActions(apFlowItem) {
2935 switch action.Type {
2936 /* not used:
2937 case of.OfpActionType_OFPAT_OUTPUT:
2938 {
mpagenko01e726e2020-10-23 09:45:29 +00002939 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002940 "Output": action.GetOutput()})
2941 }
2942 */
2943 case of.OfpActionType_OFPAT_PUSH_VLAN:
2944 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002945 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002946 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2947 }
2948 case of.OfpActionType_OFPAT_SET_FIELD:
2949 {
2950 pActionSetField := action.GetSetField()
2951 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002952 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002953 "OxcmClass": pActionSetField.Field.OxmClass})
2954 }
2955 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302956 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002957 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302958 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002959 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302960 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002961 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302962 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002963 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002964 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002965 "Type": pActionSetField.Field.GetOfbField().Type})
2966 }
2967 }
2968 /*
2969 default:
2970 {
2971 //all other entires ignored
2972 }
2973 */
2974 }
2975 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302976}
2977
2978//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
ozgecanetsia82b91a62021-05-21 18:54:49 +03002979func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort,
2980 apFlowMetaData *voltha.FlowMetadata) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302981 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2982 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2983 var loAddPcp, loSetPcp uint8
2984 var loIPProto uint32
2985 /* the TechProfileId is part of the flow Metadata - compare also comment within
2986 * OLT-Adapter:openolt_flowmgr.go
2987 * Metadata 8 bytes:
2988 * Most Significant 2 Bytes = Inner VLAN
2989 * Next 2 Bytes = Tech Profile ID(TPID)
2990 * Least Significant 4 Bytes = Port ID
2991 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2992 * subscriber related flows.
2993 */
2994
dbainbri4d3a0dc2020-12-02 00:33:42 +00002995 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302996 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002997 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302998 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002999 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303000 }
mpagenko551a4d42020-12-08 18:09:20 +00003001 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003002 loCookie := apFlowItem.GetCookie()
3003 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00003004 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003005 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05303006
dbainbri4d3a0dc2020-12-02 00:33:42 +00003007 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003008 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303009 if loIPProto == 2 {
3010 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3011 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003012 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
3013 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303014 return nil
3015 }
mpagenko01e726e2020-10-23 09:45:29 +00003016 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003017 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003018
3019 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003020 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003021 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
3022 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3023 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3024 //TODO!!: Use DeviceId within the error response to rwCore
3025 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00003026 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003027 }
3028 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003029 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003030 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3031 } else {
3032 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3033 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3034 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303035 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003036 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003037 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003038 }
mpagenko9a304ea2020-12-16 15:54:01 +00003039
ozgecanetsia82b91a62021-05-21 18:54:49 +03003040 var meter *voltha.OfpMeterConfig
3041 if apFlowMetaData != nil {
3042 meter = apFlowMetaData.Meters[0]
3043 }
mpagenkobc4170a2021-08-17 16:42:10 +00003044 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3045 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3046 // when different rules are requested concurrently for the same uni
3047 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3048 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3049 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
3050 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID, "tpID": loTpID, "uniID": apUniPort.uniID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303051 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003052 //SetUniFlowParams() may block on some rule that is suspended-to-add
3053 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
mpagenkof1fc3862021-02-16 10:09:52 +00003054 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003055 loMatchVlan, loSetVlan, loSetPcp, false, meter)
mpagenkobc4170a2021-08-17 16:42:10 +00003056 dh.lockVlanConfig.RUnlock()
3057 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
mpagenkof1fc3862021-02-16 10:09:52 +00003058 return err
mpagenkodff5dda2020-08-28 11:52:01 +00003059 }
mpagenkobc4170a2021-08-17 16:42:10 +00003060 dh.lockVlanConfig.RUnlock()
3061 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003062 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003063 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false, meter)
mpagenko7d14de12021-07-27 08:31:56 +00003064 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003065 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
mpagenko7d14de12021-07-27 08:31:56 +00003066 return err
mpagenko01e726e2020-10-23 09:45:29 +00003067}
3068
3069//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00003070func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00003071 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3072 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3073 //no extra check is done on the rule parameters
3074 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3075 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3076 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3077 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003078 // - 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 +00003079 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003080 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003081
3082 /* TT related temporary workaround - should not be needed anymore
3083 for _, field := range flow.GetOfbFields(apFlowItem) {
3084 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3085 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00003086 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003087 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3088 if loIPProto == 2 {
3089 // 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 +00003090 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00003091 log.Fields{"device-id": dh.deviceID})
3092 return nil
3093 }
3094 }
3095 } //for all OfbFields
3096 */
3097
mpagenko9a304ea2020-12-16 15:54:01 +00003098 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003099 dh.lockVlanConfig.RLock()
3100 defer dh.lockVlanConfig.RUnlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003101 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.deviceID, "uniID": apUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +00003102 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003103 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00003104 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003105 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00003106 log.Fields{"device-id": dh.deviceID})
3107 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003108 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00003109 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00003110
mpagenko01e726e2020-10-23 09:45:29 +00003111 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00003112}
3113
Himani Chawla26e555c2020-08-31 12:30:20 +05303114// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003115// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003116// precondition: dh.lockVlanConfig is locked by the caller!
mpagenko551a4d42020-12-08 18:09:20 +00003117func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003118 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
mpagenkodff5dda2020-08-28 11:52:01 +00003119 chVlanFilterFsm := make(chan Message, 2048)
3120
dbainbri4d3a0dc2020-12-02 00:33:42 +00003121 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003122 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003123 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303124 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003125 }
3126
dbainbri4d3a0dc2020-12-02 00:33:42 +00003127 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00003128 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003129 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter)
mpagenkodff5dda2020-08-28 11:52:01 +00003130 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003131 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3132 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Himani Chawla26e555c2020-08-31 12:30:20 +05303133 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003134 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3135 if pVlanFilterStatemachine != nil {
3136 if pVlanFilterStatemachine.Is(vlanStDisabled) {
3137 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003138 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05303139 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003140 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303141 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003142 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05303143 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3144 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003145 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003146 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003147 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303148 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003149 }
3150 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003151 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003152 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303153 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003154 }
3155 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003156 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003157 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05303158 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003159 }
3160 return nil
3161}
3162
mpagenkofc4f56e2020-11-04 17:17:49 +00003163//VerifyVlanConfigRequest checks on existence of a given uniPort
3164// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003165func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003166 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
3167 var pCurrentUniPort *onuUniPort
3168 for _, uniPort := range dh.uniEntityMap {
3169 // only if this port is validated for operState transfer
3170 if uniPort.uniID == uint8(aUniID) {
3171 pCurrentUniPort = uniPort
3172 break //found - end search loop
3173 }
3174 }
3175 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003176 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00003177 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
3178 return
3179 }
mpagenko551a4d42020-12-08 18:09:20 +00003180 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003181}
3182
mpagenkodff5dda2020-08-28 11:52:01 +00003183//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00003184func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003185 //TODO!! verify and start pending flow configuration
3186 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3187 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003188
3189 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303190 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003191 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003192 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
3193 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3194 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003195 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
3196 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
3197 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
3198 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
3199 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3200 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3201 } else {
3202 /***** UniVlanConfigFsm continued */
3203 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
3204 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3205 "UniPort": apUniPort.portNo})
3206 }
3207 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
3208 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
3209 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3210 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3211 } else {
3212 /***** UniVlanConfigFsm continued */
3213 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3214 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3215 "UniPort": apUniPort.portNo})
3216 }
mpagenkodff5dda2020-08-28 11:52:01 +00003217 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003218 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3219 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003220 "UniPort": apUniPort.portNo})
3221 }
3222 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003223 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3224 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3225 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003226 }
3227 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003228 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003229 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003230 }
mpagenkof1fc3862021-02-16 10:09:52 +00003231 } else {
3232 dh.lockVlanConfig.RUnlock()
3233 }
mpagenkodff5dda2020-08-28 11:52:01 +00003234}
3235
3236//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3237// 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 +00003238func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3239 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003240 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3241 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003242 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303243 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003244 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003245}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003246
mpagenkof1fc3862021-02-16 10:09:52 +00003247//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3248func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3249 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3250 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3251 // obviously then parallel processing on the cancel must be avoided
3252 // deadline context to ensure completion of background routines waited for
3253 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3254 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3255 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3256
3257 aPDevEntry.resetKvProcessingErrorIndication()
3258 var wg sync.WaitGroup
3259 wg.Add(1) // for the 1 go routine to finish
3260
3261 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3262 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3263
3264 return aPDevEntry.getKvProcessingErrorIndication()
3265}
3266
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003267//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3268//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003269func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3270 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003271
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003272 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003273 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003274 return nil
3275 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003276 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003277
dbainbri4d3a0dc2020-12-02 00:33:42 +00003278 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003279 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003280 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003281 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3282 }
3283 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3284
mpagenkof1fc3862021-02-16 10:09:52 +00003285 if aWriteToKvStore {
3286 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3287 }
3288 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003289}
3290
dbainbri4d3a0dc2020-12-02 00:33:42 +00003291func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003292 defer cancel() //ensure termination of context (may be pro forma)
3293 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003294 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003295 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003296}
3297
dbainbri4d3a0dc2020-12-02 00:33:42 +00003298func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003299
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003300 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003301 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003302 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003303 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3304 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003305 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003306 return err
3307 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003308 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003309 return nil
3310 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003311 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003312 return nil
3313}
3314
dbainbri4d3a0dc2020-12-02 00:33:42 +00003315func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3316 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003317 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003318 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003319 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3320 }
mpagenkof1fc3862021-02-16 10:09:52 +00003321 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003322}
3323
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003324// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003325// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003326func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3327 dh.lockDevice.RLock()
3328 defer dh.lockDevice.RUnlock()
3329 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3330 return uniPort.entityID, nil
3331 }
3332 return 0, errors.New("error-fetching-uni-port")
3333}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003334
3335// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003336func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3337 var errorsList []error
3338 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 -08003339
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003340 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3341 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3342 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3343
3344 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3345 // successfully.
3346 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3347 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3348 if len(errorsList) > 0 {
3349 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3350 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003351 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003352 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3353 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003354}
3355
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003356func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3357 var err error
3358 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003359 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003360
3361 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3362 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3363 errorsList = append(errorsList, err)
3364 }
3365 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003366 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003367
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003368 return errorsList
3369}
3370
3371func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3372 var err error
3373 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003374 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003375 // Check if group metric related config is updated
3376 for _, v := range pmConfigs.Groups {
3377 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3378 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3379 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3380
3381 if ok && m.frequency != v.GroupFreq {
3382 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3383 errorsList = append(errorsList, err)
3384 }
3385 }
3386 if ok && m.enabled != v.Enabled {
3387 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3388 errorsList = append(errorsList, err)
3389 }
3390 }
3391 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003392 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003393 return errorsList
3394}
3395
3396func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3397 var err error
3398 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003399 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003400 // Check if standalone metric related config is updated
3401 for _, v := range pmConfigs.Metrics {
3402 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003403 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003404 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3405
3406 if ok && m.frequency != v.SampleFreq {
3407 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3408 errorsList = append(errorsList, err)
3409 }
3410 }
3411 if ok && m.enabled != v.Enabled {
3412 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3413 errorsList = append(errorsList, err)
3414 }
3415 }
3416 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003417 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003418 return errorsList
3419}
3420
3421// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003422func (dh *deviceHandler) startCollector(ctx context.Context) {
3423 logger.Debugf(ctx, "startingCollector")
3424
3425 // Start routine to process OMCI GET Responses
3426 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303427 // Create Extended Frame PM ME
3428 go dh.pOnuMetricsMgr.createEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003429 // Initialize the next metric collection time.
3430 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3431 // reset like onu rebooted.
3432 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003433 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003434 for {
3435 select {
3436 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003437 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003438 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003439 // Stop the L2 PM FSM
3440 go func() {
3441 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3442 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3443 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3444 }
3445 } else {
3446 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3447 }
3448 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003449 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3450 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3451 }
3452 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3453 dh.pOnuMetricsMgr.stopTicks <- true
3454 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003455
Girish Gowdrae09a6202021-01-12 18:10:59 -08003456 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003457 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3458 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3459 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3460 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3461 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003462 // Update the next metric collection time.
3463 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003464 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003465 } else {
3466 if dh.pmConfigs.Grouped { // metrics are managed as a group
3467 // parse through the group and standalone metrics to see it is time to collect their metrics
3468 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003469
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003470 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3471 // 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 -08003472 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3473 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003474 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3475 }
3476 }
3477 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3478 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3479 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3480 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3481 }
3482 }
3483 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3484
3485 // parse through the group and update the next metric collection time
3486 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3487 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3488 // 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 -08003489 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3490 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003491 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3492 }
3493 }
3494 // parse through the standalone metrics and update the next metric collection time
3495 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3496 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3497 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3498 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3499 }
3500 }
3501 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3502 } /* else { // metrics are not managed as a group
3503 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3504 } */
3505 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003506 }
3507 }
3508}
kesavandfdf77632021-01-26 23:40:33 -05003509
3510func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3511
3512 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3513 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3514}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003515
Himani Chawla43f95ff2021-06-03 00:24:12 +05303516func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3517 if dh.pOnuMetricsMgr == nil {
3518 return &extension.SingleGetValueResponse{
3519 Response: &extension.GetValueResponse{
3520 Status: extension.GetValueResponse_ERROR,
3521 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3522 },
3523 }
3524 }
3525 resp := dh.pOnuMetricsMgr.collectEthernetFrameExtendedPMCounters(ctx)
3526 return resp
3527}
3528
mpagenkof1fc3862021-02-16 10:09:52 +00003529func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3530 if pFsm == nil {
3531 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003532 }
mpagenkof1fc3862021-02-16 10:09:52 +00003533 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003534}
3535
mpagenkof1fc3862021-02-16 10:09:52 +00003536func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3537 var pFsm *fsm.FSM
3538 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3539 switch omciFsm {
3540 case cUploadFsm:
3541 {
3542 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3543 }
3544 case cDownloadFsm:
3545 {
3546 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3547 }
3548 case cUniLockFsm:
3549 {
3550 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3551 }
3552 case cUniUnLockFsm:
3553 {
3554 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3555 }
3556 case cL2PmFsm:
3557 {
3558 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3559 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3560 } else {
3561 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003562 }
3563 }
mpagenko80622a52021-02-09 16:53:23 +00003564 case cOnuUpgradeFsm:
3565 {
3566 dh.lockUpgradeFsm.RLock()
3567 defer dh.lockUpgradeFsm.RUnlock()
3568 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3569 }
mpagenkof1fc3862021-02-16 10:09:52 +00003570 default:
3571 {
3572 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3573 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3574 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003575 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003576 }
mpagenkof1fc3862021-02-16 10:09:52 +00003577 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003578}
3579
mpagenkof1fc3862021-02-16 10:09:52 +00003580func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3581 for _, v := range dh.pOnuTP.pAniConfigFsm {
3582 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003583 return false
3584 }
3585 }
3586 return true
3587}
3588
mpagenkof1fc3862021-02-16 10:09:52 +00003589func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3590 dh.lockVlanConfig.RLock()
3591 defer dh.lockVlanConfig.RUnlock()
3592 for _, v := range dh.UniVlanConfigFsmMap {
3593 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3594 return false
3595 }
3596 }
3597 return true //FSM not active - so there is no activity on omci
3598}
3599
3600func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3601 dh.lockVlanConfig.RLock()
3602 defer dh.lockVlanConfig.RUnlock()
3603 for _, v := range dh.UniVlanConfigFsmMap {
3604 if v.pAdaptFsm.pFsm != nil {
3605 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3606 return true //there is at least one VLAN FSM with some active configuration
3607 }
3608 }
3609 }
3610 return false //there is no VLAN FSM with some active configuration
3611}
3612
3613func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3614 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3615 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3616 return false
3617 }
3618 }
3619 // a further check is done to identify, if at least some data traffic related configuration exists
3620 // 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])
3621 return dh.checkUserServiceExists(ctx)
3622}
3623
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003624func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3625 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3626 if err := dh.resetFsms(ctx, false); err != nil {
3627 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3628 // TODO: fatal error reset ONU, delete deviceHandler!
3629 return
3630 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003631 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003632 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003633}
3634
3635func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3636 dh.mutexCollectorFlag.Lock()
3637 dh.collectorIsRunning = flagValue
3638 dh.mutexCollectorFlag.Unlock()
3639}
3640
3641func (dh *deviceHandler) getCollectorIsRunning() bool {
3642 dh.mutexCollectorFlag.RLock()
3643 flagValue := dh.collectorIsRunning
3644 dh.mutexCollectorFlag.RUnlock()
3645 return flagValue
3646}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303647
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303648func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3649 dh.mutextAlarmManagerFlag.Lock()
3650 dh.alarmManagerIsRunning = flagValue
3651 dh.mutextAlarmManagerFlag.Unlock()
3652}
3653
Himani Chawla1472c682021-03-17 17:11:14 +05303654func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303655 dh.mutextAlarmManagerFlag.RLock()
3656 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303657 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303658 dh.mutextAlarmManagerFlag.RUnlock()
3659 return flagValue
3660}
3661
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303662func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3663 logger.Debugf(ctx, "startingAlarmManager")
3664
3665 // Start routine to process OMCI GET Responses
3666 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303667 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303668 if stop := <-dh.stopAlarmManager; stop {
3669 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303670 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303671 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303672 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3673 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3674 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303675 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303676 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303677 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3678 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303679 }
3680}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003681
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003682func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003683 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003684
Maninder7961d722021-06-16 22:10:28 +05303685 connectStatus := voltha.ConnectStatus_UNREACHABLE
3686 operState := voltha.OperStatus_UNKNOWN
3687
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003688 if !dh.isReconciling() {
3689 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003690 logger.Debugw(ctx, "wait for channel signal or timeout",
3691 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003692 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003693 case success := <-dh.chReconcilingFinished:
3694 if success {
Maninderb5187552021-03-23 22:23:42 +05303695 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3696 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3697 log.Fields{"device-id": dh.deviceID})
3698 } else {
Maninderb5187552021-03-23 22:23:42 +05303699 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3700 connectStatus = voltha.ConnectStatus_REACHABLE
3701 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3702 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3703 operState = voltha.OperStatus_ACTIVE
3704 } else {
3705 operState = voltha.OperStatus_ACTIVATING
3706 }
3707 }
3708 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3709 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3710 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3711 operState = voltha.OperStatus_DISCOVERED
3712 }
3713
3714 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303715 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003716 logger.Debugw(ctx, "reconciling has been finished in time",
3717 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303718 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, operState); err != nil {
3719 logger.Errorw(ctx, "unable to update device state to core",
3720 log.Fields{"device-id": dh.deviceID, "Err": err})
3721 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003722 } else {
Maninderb5187552021-03-23 22:23:42 +05303723 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003724 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303725
3726 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3727 logger.Errorw(ctx, "No valid OnuDevice",
3728 log.Fields{"device-id": dh.deviceID})
3729 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3730 connectStatus = voltha.ConnectStatus_REACHABLE
3731 }
3732
3733 dh.deviceReconcileFailedUpdate(ctx, drReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003734 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003735 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003736 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3737 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303738
3739 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3740 logger.Errorw(ctx, "No valid OnuDevice",
3741 log.Fields{"device-id": dh.deviceID})
3742 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3743 connectStatus = voltha.ConnectStatus_REACHABLE
3744 }
3745
3746 dh.deviceReconcileFailedUpdate(ctx, drReconcileMaxTimeout, connectStatus)
3747
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003748 }
3749 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003750 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003751 dh.mutexReconcilingFlag.Unlock()
3752 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003753 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003754 dh.mutexReconcilingFlag.Lock()
3755 if skipOnuConfig {
3756 dh.reconciling = cSkipOnuConfigReconciling
3757 } else {
3758 dh.reconciling = cOnuConfigReconciling
3759 }
3760 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003761}
3762
Girish Gowdra50e56422021-06-01 16:46:04 -07003763func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool) {
3764 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID, "success": success})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003765 if dh.isReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07003766 dh.chReconcilingFinished <- success
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003767 } else {
3768 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3769 }
3770}
3771
3772func (dh *deviceHandler) isReconciling() bool {
3773 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003774 defer dh.mutexReconcilingFlag.RUnlock()
3775 return dh.reconciling != cNoReconciling
3776}
3777
3778func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3779 dh.mutexReconcilingFlag.RLock()
3780 defer dh.mutexReconcilingFlag.RUnlock()
3781 return dh.reconciling == cSkipOnuConfigReconciling
3782}
3783
3784func (dh *deviceHandler) setDeviceReason(value uint8) {
3785 dh.mutexDeviceReason.Lock()
3786 dh.deviceReason = value
3787 dh.mutexDeviceReason.Unlock()
3788}
3789
3790func (dh *deviceHandler) getDeviceReason() uint8 {
3791 dh.mutexDeviceReason.RLock()
3792 value := dh.deviceReason
3793 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003794 return value
3795}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003796
3797func (dh *deviceHandler) getDeviceReasonString() string {
3798 return deviceReasonMap[dh.getDeviceReason()]
3799}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003800
3801func (dh *deviceHandler) setReconcilingFlows(value bool) {
3802 dh.mutexReconcilingFlowsFlag.Lock()
3803 dh.reconcilingFlows = value
3804 dh.mutexReconcilingFlowsFlag.Unlock()
3805}
3806
3807func (dh *deviceHandler) isReconcilingFlows() bool {
3808 dh.mutexReconcilingFlowsFlag.RLock()
3809 value := dh.reconcilingFlows
3810 dh.mutexReconcilingFlowsFlag.RUnlock()
3811 return value
3812}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003813
3814func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3815 dh.mutexReadyForOmciConfig.Lock()
3816 dh.readyForOmciConfig = flagValue
3817 dh.mutexReadyForOmciConfig.Unlock()
3818}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003819func (dh *deviceHandler) isReadyForOmciConfig() bool {
3820 dh.mutexReadyForOmciConfig.RLock()
3821 flagValue := dh.readyForOmciConfig
3822 dh.mutexReadyForOmciConfig.RUnlock()
3823 return flagValue
3824}
Maninder7961d722021-06-16 22:10:28 +05303825
3826func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
3827 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
3828 logger.Errorw(ctx, "unable to update device reason to core",
3829 log.Fields{"device-id": dh.deviceID, "Err": err})
3830 }
3831
3832 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
3833 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, voltha.OperStatus_RECONCILING_FAILED); err != nil {
3834 logger.Errorw(ctx, "unable to update device state to core",
3835 log.Fields{"device-id": dh.deviceID, "Err": err})
3836 }
3837}