blob: 4a831eb3f27a51471692ad6f6322062bc1e755ae [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
mpagenko9c225032021-10-15 14:26:49 +000049// Constants for timeouts
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000050const (
mpagenko9c225032021-10-15 14:26:49 +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 (
Holger Hildebrandt3d77f9c2022-01-12 10:45:13 +000055 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
56 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
57 // as long as such is not available by the libraries - use this workaround
58 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
59)
60
61const (
mpagenko1cc3cb42020-07-27 15:24:38 +000062 // events of Device FSM
63 devEvDeviceInit = "devEvDeviceInit"
64 devEvGrpcConnected = "devEvGrpcConnected"
65 devEvGrpcDisconnected = "devEvGrpcDisconnected"
66 devEvDeviceUpInd = "devEvDeviceUpInd"
67 devEvDeviceDownInd = "devEvDeviceDownInd"
68)
69const (
70 // states of Device FSM
71 devStNull = "devStNull"
72 devStDown = "devStDown"
73 devStInit = "devStInit"
74 devStConnected = "devStConnected"
75 devStUp = "devStUp"
76)
77
Holger Hildebrandt24d51952020-05-04 14:03:42 +000078//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
79const (
Himani Chawla4d908332020-08-31 12:30:20 +053080 pon = voltha.EventSubCategory_PON
81 //olt = voltha.EventSubCategory_OLT
82 //ont = voltha.EventSubCategory_ONT
83 //onu = voltha.EventSubCategory_ONU
84 //nni = voltha.EventSubCategory_NNI
85 //service = voltha.EventCategory_SERVICE
86 //security = voltha.EventCategory_SECURITY
87 equipment = voltha.EventCategory_EQUIPMENT
88 //processing = voltha.EventCategory_PROCESSING
89 //environment = voltha.EventCategory_ENVIRONMENT
90 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000091)
92
93const (
94 cEventObjectType = "ONU"
95)
96const (
97 cOnuActivatedEvent = "ONU_ACTIVATED"
98)
99
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000100type usedOmciConfigFsms int
101
102const (
103 cUploadFsm usedOmciConfigFsms = iota
104 cDownloadFsm
105 cUniLockFsm
106 cUniUnLockFsm
107 cAniConfigFsm
108 cUniVlanConfigFsm
Girish Gowdrae0140f02021-02-02 16:55:09 -0800109 cL2PmFsm
mpagenko80622a52021-02-09 16:53:23 +0000110 cOnuUpgradeFsm
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000111)
112
mpagenkof1fc3862021-02-16 10:09:52 +0000113type omciIdleCheckStruct struct {
114 omciIdleCheckFunc func(*deviceHandler, context.Context, usedOmciConfigFsms, string) bool
115 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000116}
117
mpagenkof1fc3862021-02-16 10:09:52 +0000118var fsmOmciIdleStateFuncMap = map[usedOmciConfigFsms]omciIdleCheckStruct{
119 cUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibUlFsmIdleState},
120 cDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibDlFsmIdleState},
121 cUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
122 cUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
123 cAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, cAniFsmIdleState},
124 cUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, cVlanFsmIdleState},
125 cL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cL2PmFsmIdleState},
mpagenko80622a52021-02-09 16:53:23 +0000126 cOnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cOnuUpgradeFsmIdleState},
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000127}
128
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000129const (
130 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000131 drUnset = 0
132 drActivatingOnu = 1
133 drStartingOpenomci = 2
134 drDiscoveryMibsyncComplete = 3
135 drInitialMibDownloaded = 4
136 drTechProfileConfigDownloadSuccess = 5
137 drOmciFlowsPushed = 6
138 drOmciAdminLock = 7
139 drOnuReenabled = 8
140 drStoppingOpenomci = 9
141 drRebooting = 10
142 drOmciFlowsDeleted = 11
143 drTechProfileConfigDeleteSuccess = 12
Maninder7961d722021-06-16 22:10:28 +0530144 drReconcileFailed = 13
145 drReconcileMaxTimeout = 14
146 drReconcileCanceled = 15
Girish Gowdra50e56422021-06-01 16:46:04 -0700147 drTechProfileConfigDownloadFailed = 16
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000148)
149
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000150var deviceReasonMap = map[uint8]string{
151 drUnset: "unset",
152 drActivatingOnu: "activating-onu",
153 drStartingOpenomci: "starting-openomci",
154 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
155 drInitialMibDownloaded: "initial-mib-downloaded",
156 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
Girish Gowdra50e56422021-06-01 16:46:04 -0700157 drTechProfileConfigDownloadFailed: "tech-profile-config-download-failed",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000158 drOmciFlowsPushed: "omci-flows-pushed",
159 drOmciAdminLock: "omci-admin-lock",
160 drOnuReenabled: "onu-reenabled",
161 drStoppingOpenomci: "stopping-openomci",
162 drRebooting: "rebooting",
163 drOmciFlowsDeleted: "omci-flows-deleted",
164 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
Maninder7961d722021-06-16 22:10:28 +0530165 drReconcileFailed: "reconcile-failed",
166 drReconcileMaxTimeout: "reconcile-max-timeout",
167 drReconcileCanceled: "reconciling-canceled",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000168}
169
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000170const (
171 cNoReconciling = iota
172 cOnuConfigReconciling
173 cSkipOnuConfigReconciling
174)
175
Himani Chawla6d2ae152020-09-02 13:11:20 +0530176//deviceHandler will interact with the ONU ? device.
177type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000178 deviceID string
179 DeviceType string
180 adminState string
181 device *voltha.Device
182 logicalDeviceID string
183 ProxyAddressID string
184 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530185 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000186 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000187
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000188 coreProxy adapterif.CoreProxy
189 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530190 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000191
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800192 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800193
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000194 pOpenOnuAc *OpenONUAC
195 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530196 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000197 deviceEntrySet chan bool //channel for DeviceEntry set event
198 pOnuOmciDevice *OnuDeviceEntry
199 pOnuTP *onuUniTechProf
200 pOnuMetricsMgr *onuMetricsManager
201 pAlarmMgr *onuAlarmManager
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700202 pSelfTestHdlr *selfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000203 exitChannel chan int
204 lockDevice sync.RWMutex
205 pOnuIndication *oop.OnuIndication
206 deviceReason uint8
207 mutexDeviceReason sync.RWMutex
208 pLockStateFsm *lockStateFsm
209 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000210
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000211 //flowMgr *OpenOltFlowMgr
212 //eventMgr *OpenOltEventMgr
213 //resourceMgr *rsrcMgr.OpenOltResourceMgr
214
215 //discOnus sync.Map
216 //onus sync.Map
217 //portStats *OpenOltStatisticsMgr
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000218 collectorIsRunning bool
219 mutexCollectorFlag sync.RWMutex
220 stopCollector chan bool
221 alarmManagerIsRunning bool
222 mutextAlarmManagerFlag sync.RWMutex
223 stopAlarmManager chan bool
224 stopHeartbeatCheck chan bool
225 uniEntityMap map[uint32]*onuUniPort
226 mutexKvStoreContext sync.Mutex
227 lockVlanConfig sync.RWMutex
mpagenko2f487262021-08-23 15:59:06 +0000228 lockVlanAdd sync.RWMutex
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000229 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
230 lockUpgradeFsm sync.RWMutex
231 pOnuUpradeFsm *OnuUpgradeFsm
mpagenko9c225032021-10-15 14:26:49 +0000232 upgradeCanceled bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000233 reconciling uint8
234 mutexReconcilingFlag sync.RWMutex
235 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000236 reconcilingFlows bool
237 mutexReconcilingFlowsFlag sync.RWMutex
238 chReconcilingFlowsFinished chan bool //channel to indicate that reconciling of flows has been finished
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000239 mutexReadyForOmciConfig sync.RWMutex
240 readyForOmciConfig bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000241 deletionInProgress bool
242 mutexDeletionInProgressFlag sync.RWMutex
mpagenko9c225032021-10-15 14:26:49 +0000243 pLastUpgradeImageState *voltha.ImageState
244 upgradeFsmChan chan struct{}
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000245}
246
Himani Chawla6d2ae152020-09-02 13:11:20 +0530247//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530248func 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 +0530249 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000250 dh.coreProxy = cp
251 dh.AdapterProxy = ap
252 dh.EventProxy = ep
253 cloned := (proto.Clone(device)).(*voltha.Device)
254 dh.deviceID = cloned.Id
255 dh.DeviceType = cloned.Type
256 dh.adminState = "up"
257 dh.device = cloned
258 dh.pOpenOnuAc = adapter
259 dh.exitChannel = make(chan int, 1)
260 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000261 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000262 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000263 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530264 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530265 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000266 dh.stopHeartbeatCheck = make(chan bool, 2)
267 //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 +0000268 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530269 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000270 dh.lockVlanConfig = sync.RWMutex{}
mpagenko2f487262021-08-23 15:59:06 +0000271 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000272 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000273 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000274 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000275 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000276 dh.reconcilingFlows = false
277 dh.chReconcilingFlowsFinished = make(chan bool)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000278 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000279 dh.deletionInProgress = false
mpagenko9c225032021-10-15 14:26:49 +0000280 dh.pLastUpgradeImageState = &voltha.ImageState{
281 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
282 Reason: voltha.ImageState_UNKNOWN_ERROR,
283 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
284 }
285 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800287 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
288 dh.pmConfigs = cloned.PmConfigs
289 } /* else {
290 // will be populated when onu_metrics_mananger is initialized.
291 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800292
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000293 // Device related state machine
294 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000295 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000296 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000297 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
298 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
299 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
300 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
301 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000302 },
303 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000304 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
305 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
306 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
307 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
308 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
309 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
310 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
311 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000312 },
313 )
mpagenkoaf801632020-07-03 10:00:42 +0000314
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000315 return &dh
316}
317
Himani Chawla6d2ae152020-09-02 13:11:20 +0530318// start save the device to the data model
319func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000320 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000321 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000322 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000323}
324
Himani Chawla4d908332020-08-31 12:30:20 +0530325/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000326// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530327func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000328 logger.Debug("stopping-device-handler")
329 dh.exitChannel <- 1
330}
Himani Chawla4d908332020-08-31 12:30:20 +0530331*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000332
333// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530334// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000335
Girish Gowdrae0140f02021-02-02 16:55:09 -0800336//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530337func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000338 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000339
dbainbri4d3a0dc2020-12-02 00:33:42 +0000340 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000341 if dh.pDeviceStateFsm.Is(devStNull) {
342 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000343 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000344 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000345 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800346 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
347 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800348 // Now, set the initial PM configuration for that device
349 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
350 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
351 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800352 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000353 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000354 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000355 }
356
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000357}
358
mpagenko057889c2021-01-21 16:51:58 +0000359func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530360 msgBody := msg.GetBody()
361 omciMsg := &ic.InterAdapterOmciMessage{}
362 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000363 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530364 "device-id": dh.deviceID, "error": err})
365 return err
366 }
367
mpagenko80622a52021-02-09 16:53:23 +0000368 /* 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 +0530369 //assuming omci message content is hex coded!
370 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000371 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530372 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000373 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000374 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530375 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000376 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000377 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000378 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000379 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 +0530380 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000381 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000382 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530383}
384
Himani Chawla6d2ae152020-09-02 13:11:20 +0530385func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000386 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530387 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000388
dbainbri4d3a0dc2020-12-02 00:33:42 +0000389 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000390
dbainbri4d3a0dc2020-12-02 00:33:42 +0000391 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000392 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000393 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000394 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
395 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530396 if dh.pOnuTP == nil {
397 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000398 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530399 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000400 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530401 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000402 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000403 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000404 "device-state": dh.getDeviceReasonString()})
405 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530406 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000407 //previous state test here was just this one, now extended for more states to reject the SetRequest:
408 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
409 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530410
411 msgBody := msg.GetBody()
412 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
413 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000414 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530415 "device-id": dh.deviceID, "error": err})
416 return err
417 }
418
419 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000420 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
421 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530422 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000423 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000424
425 if techProfMsg.UniId > 255 {
426 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
427 techProfMsg.UniId, dh.deviceID))
428 }
429 uniID := uint8(techProfMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700430 tpID, err := GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800431 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700432 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800433 return err
434 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700435 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000436
Girish Gowdra50e56422021-06-01 16:46:04 -0700437 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530438
Girish Gowdra50e56422021-06-01 16:46:04 -0700439 switch tpInst := techProfMsg.TechTpInstance.(type) {
440 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance:
441 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
442 // if there has been some change for some uni TechProfilePath
443 //in order to allow concurrent calls to other dh instances we do not wait for execution here
444 //but doing so we can not indicate problems to the caller (who does what with that then?)
445 //by now we just assume straightforward successful execution
446 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
447 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530448
Girish Gowdra50e56422021-06-01 16:46:04 -0700449 // deadline context to ensure completion of background routines waited for
450 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
451 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
452 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000453
Girish Gowdra50e56422021-06-01 16:46:04 -0700454 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
455
456 var wg sync.WaitGroup
457 wg.Add(1) // for the 1 go routine to finish
458 // attention: deadline completion check and wg.Done is to be done in both routines
459 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
460 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
461 if tpErr := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
462 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.deviceID, "err": tpErr, "tp-path": techProfMsg.TpInstancePath})
463 return tpErr
464 }
465 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
466 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
467 pDevEntry.resetKvProcessingErrorIndication()
468 wg.Add(1) // for the 1 go routine to finish
469 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
470 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
471 if kvErr := pDevEntry.getKvProcessingErrorIndication(); kvErr != nil {
472 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.deviceID, "err": kvErr, "tp-path": techProfMsg.TpInstancePath})
473 return kvErr
474 }
475 return nil
476 default:
477 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"tp-path": techProfMsg.TpInstancePath})
478 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700479 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530480 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000481 // no change, nothing really to do - return success
Girish Gowdra50e56422021-06-01 16:46:04 -0700482 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 +0530483 return nil
484}
485
Himani Chawla6d2ae152020-09-02 13:11:20 +0530486func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000487 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530488 msg *ic.InterAdapterMessage) error {
489
490 if dh.pOnuTP == nil {
491 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000492 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530493 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000494 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530495 }
496
497 msgBody := msg.GetBody()
498 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
499 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000500 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530501 "device-id": dh.deviceID, "error": err})
502 return err
503 }
504
505 //compare TECH_PROFILE_DOWNLOAD_REQUEST
506 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000507 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530508
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000509 if delGemPortMsg.UniId > 255 {
510 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
511 delGemPortMsg.UniId, dh.deviceID))
512 }
513 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700514 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800515 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700516 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 -0800517 return err
518 }
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700519 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 +0000520 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000521
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700522 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
523 cResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000524
Himani Chawla26e555c2020-08-31 12:30:20 +0530525}
526
Himani Chawla6d2ae152020-09-02 13:11:20 +0530527func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000528 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530529 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000530
dbainbri4d3a0dc2020-12-02 00:33:42 +0000531 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000532 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000533 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000534 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
535 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530536 if dh.pOnuTP == nil {
537 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000538 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530539 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000540 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530541 }
542
543 msgBody := msg.GetBody()
544 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
545 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000546 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530547 "device-id": dh.deviceID, "error": err})
548 return err
549 }
550
551 //compare TECH_PROFILE_DOWNLOAD_REQUEST
552 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000553 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000554
555 if delTcontMsg.UniId > 255 {
556 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
557 delTcontMsg.UniId, dh.deviceID))
558 }
559 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700560 tpPath := delTcontMsg.TpInstancePath
Girish Gowdra041dcb32020-11-16 16:54:30 -0800561 tpID, err := GetTpIDFromTpPath(tpPath)
562 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000563 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800564 return err
565 }
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700566 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 +0000567
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700568 pDevEntry.freeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530569
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700570 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
571 cResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000572
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700573}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000574
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700575func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
576 uniID uint8, tpID uint8, pathString string, resource resourceEntry, entryID uint32) error {
577 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
578 if pDevEntry == nil {
579 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
580 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530581 }
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700582 var resourceName string
583 if cResourceGemPort == resource {
584 resourceName = "Gem"
585 } else {
586 resourceName = "Tcont"
587 }
588
589 // deadline context to ensure completion of background routines waited for
590 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
591 dctx, cancel := context.WithDeadline(context.Background(), deadline)
592
593 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
594
595 var wg sync.WaitGroup
596 wg.Add(1) // for the 1 go routine to finish
597 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
598 resource, entryID, &wg)
599 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
600 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); err != nil {
601 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
602 return err
603 }
604
605 if dh.pOnuTP.isTechProfileConfigCleared(ctx, uniID, tpID) {
606 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID})
607 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
608 pDevEntry.resetKvProcessingErrorIndication()
609 var wg2 sync.WaitGroup
610 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
611 wg2.Add(1)
612 // Removal of the gem id mapping represents the removal of the tech profile
613 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID})
614 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
615 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
616 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
617 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
618 return err
619 }
620 }
621 }
622 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.deviceID,
623 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530624 return nil
625}
626
Himani Chawla6d2ae152020-09-02 13:11:20 +0530627//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000628// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
629// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000630func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000631 msgID := msg.Header.Id
632 msgType := msg.Header.Type
633 fromTopic := msg.Header.FromTopic
634 toTopic := msg.Header.ToTopic
635 toDeviceID := msg.Header.ToDeviceId
636 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000637 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000638 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
639
640 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000641 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000642 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
643 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000644 {
mpagenko057889c2021-01-21 16:51:58 +0000645 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000646 }
mpagenkoaf801632020-07-03 10:00:42 +0000647 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
648 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000649 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000650 }
651 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
652 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000653 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000654
mpagenkoaf801632020-07-03 10:00:42 +0000655 }
656 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
657 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000658 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000659 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000660 default:
661 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000662 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000663 "msgType": msg.Header.Type, "device-id": dh.deviceID})
664 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000665 }
666 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000667}
668
mpagenkodff5dda2020-08-28 11:52:01 +0000669//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000670func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
671 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000672 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
ozgecanetsia82b91a62021-05-21 18:54:49 +0300673 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID, "metadata": apFlowMetaData})
mpagenko01e726e2020-10-23 09:45:29 +0000674 var retError error = nil
675 //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 +0000676 if apOfFlowChanges.ToRemove != nil {
677 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000678 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000679 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000680 "device-id": dh.deviceID})
681 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000682 continue
683 }
684 flowInPort := flow.GetInPort(flowItem)
685 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000686 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 +0000687 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
688 continue
689 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000690 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000691 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000692 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000693 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000694 continue
695 } else {
696 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530697 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000698 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
699 loUniPort = uniPort
700 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000701 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000702 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
703 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
704 flowInPort, dh.deviceID)
705 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000706 }
707 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000708 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000709 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000710 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000711 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000712 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000713 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000714 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000715 log.Fields{"device-id": dh.deviceID, "error": err})
716 retError = err
717 continue
718 //return err
719 } else { // if last setting succeeds, overwrite possibly previously set error
720 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000721 }
722 }
723 }
724 }
mpagenko01e726e2020-10-23 09:45:29 +0000725 if apOfFlowChanges.ToAdd != nil {
726 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
727 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000728 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000729 "device-id": dh.deviceID})
730 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
731 continue
732 }
733 flowInPort := flow.GetInPort(flowItem)
734 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000735 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 +0000736 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
737 continue
738 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
739 } else if flowInPort == dh.ponPortNumber {
740 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000741 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000742 "device-id": dh.deviceID, "inPort": flowInPort})
743 continue
744 } else {
745 // this is the relevant upstream flow
746 var loUniPort *onuUniPort
747 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
748 loUniPort = uniPort
749 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000750 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000751 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
752 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
753 flowInPort, dh.deviceID)
754 continue
755 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
756 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000757 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
758 // if not, we just throw some error here to have an indication about that, if we really need to support that
759 // then we would need to create some means to activate the internal stored flows
760 // after the device gets active automatically (and still with its dependency to the TechProfile)
761 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
762 // also abort for the other still possible flows here
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000763 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000764 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000765 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000766 return fmt.Errorf("improper device state on device %s", dh.deviceID)
767 }
768
mpagenko01e726e2020-10-23 09:45:29 +0000769 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000770 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000771 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
772 "uniPortName": loUniPort.name})
ozgecanetsia82b91a62021-05-21 18:54:49 +0300773 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort, apFlowMetaData)
mpagenko01e726e2020-10-23 09:45:29 +0000774 //try next flow after processing error
775 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000776 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000777 log.Fields{"device-id": dh.deviceID, "error": err})
778 retError = err
779 continue
780 //return err
781 } else { // if last setting succeeds, overwrite possibly previously set error
782 retError = nil
783 }
784 }
785 }
786 }
787 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000788}
789
Himani Chawla6d2ae152020-09-02 13:11:20 +0530790//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000791//following are the expected device states after this activity:
792//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
793// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000794func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
795 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000796
mpagenko900ee4b2020-10-12 11:56:34 +0000797 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000798 //note that disableDevice sequences in some 'ONU active' state may yield also
799 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000800 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000801 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000802 //disable-device shall be just a UNi/ONU-G related admin state setting
803 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000804
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000805 if dh.isReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000806 // disable UNI ports/ONU
807 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
808 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000809 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000810 } else { //LockStateFSM already init
811 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000812 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000813 }
814 } else {
Holger Hildebrandt3d77f9c2022-01-12 10:45:13 +0000815 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000816 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
Holger Hildebrandt3d77f9c2022-01-12 10:45:13 +0000817 // disable device should have no impact on ConnStatus
818 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
819 connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
820 voltha.OperStatus_UNKNOWN); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000821 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000822 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000823 }
mpagenko01e726e2020-10-23 09:45:29 +0000824 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000825
826 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000827 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000828 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300829 }
830}
831
Himani Chawla6d2ae152020-09-02 13:11:20 +0530832//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000833func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
834 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000835
mpagenkoaa3afe92021-05-21 16:20:58 +0000836 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000837 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
838 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
839 // for real ONU's that should have nearly no influence
840 // Note that for real ONU's there is anyway a problematic situation with following sequence:
841 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
842 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
843 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000844 dh.setReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000845
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000846 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000847 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000848 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000849 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000850 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000851 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000852 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000853 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300854}
855
dbainbri4d3a0dc2020-12-02 00:33:42 +0000856func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
857 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000858
dbainbri4d3a0dc2020-12-02 00:33:42 +0000859 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000860 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000861 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000862 return
863 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000864 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000865 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000866 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000867 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000868 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000869 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700870 dh.stopReconciling(ctx, false)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000871 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000872 }
Himani Chawla4d908332020-08-31 12:30:20 +0530873 var onuIndication oop.OnuIndication
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000874 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000875 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
876 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
877 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
878 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000879 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000880 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000881}
882
dbainbri4d3a0dc2020-12-02 00:33:42 +0000883func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
884 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000885
dbainbri4d3a0dc2020-12-02 00:33:42 +0000886 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000887 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000888 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000889 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700890 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000891 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000892 return
893 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000894 dh.pOnuTP.lockTpProcMutex()
895 defer dh.pOnuTP.unlockTpProcMutex()
896
mpagenko5dc85a02021-08-02 12:35:01 +0000897 pDevEntry.mutexPersOnuConfig.RLock()
898 persMutexLock := true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000899 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko5dc85a02021-08-02 12:35:01 +0000900 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000901 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000902 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000903 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700904 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000905 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000906 return
907 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000908 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700909 techProfsFound := false
910 techProfInstLoadFailed := false
911outerLoop:
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000912 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000913 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
914 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000915 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000916 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000917 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000918 }
mpagenko5dc85a02021-08-02 12:35:01 +0000919 //release mutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
920 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
921 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
922 pDevEntry.mutexPersOnuConfig.RUnlock()
923 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700924 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800925 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700926 // Request the TpInstance again from the openolt adapter in case of reconcile
927 iaTechTpInst, err := dh.AdapterProxy.TechProfileInstanceRequest(ctx, uniData.PersTpPathMap[tpID],
928 dh.device.ParentPortNo, dh.device.ProxyAddress.OnuId, uint32(uniData.PersUniID),
929 dh.pOpenOnuAc.config.Topic, dh.ProxyAddressType,
930 dh.parentID, dh.ProxyAddressID)
931 if err != nil || iaTechTpInst == nil {
932 logger.Errorw(ctx, "error fetching tp instance",
933 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID, "err": err})
934 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
935 break outerLoop
936 }
937 var tpInst tech_profile.TechProfileInstance
938 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
939 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
940 tpInst = *techTpInst.TpInstance
mpagenko5dc85a02021-08-02 12:35:01 +0000941 logger.Debugw(ctx, "received-tp-instance-successfully-after-reconcile", log.Fields{
942 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700943 default: // do not support epon or other tech
mpagenko5dc85a02021-08-02 12:35:01 +0000944 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
945 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700946 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
947 break outerLoop
948 }
949
Girish Gowdra041dcb32020-11-16 16:54:30 -0800950 // deadline context to ensure completion of background routines waited for
951 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
952 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000953 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000954
Girish Gowdra041dcb32020-11-16 16:54:30 -0800955 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
956 var wg sync.WaitGroup
957 wg.Add(1) // for the 1 go routine to finish
Girish Gowdra50e56422021-06-01 16:46:04 -0700958 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000959 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800960 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000961 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700962 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
963 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800964 }
mpagenko5dc85a02021-08-02 12:35:01 +0000965 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000966 if len(uniData.PersFlowParams) != 0 {
967 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000968 }
mpagenko5dc85a02021-08-02 12:35:01 +0000969 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
970 persMutexLock = true
971 } // for all UNI entries from sOnuPersistentData
972 if persMutexLock { // if loop was left with mutexPersOnuConfig still set
973 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000974 }
mpagenko5dc85a02021-08-02 12:35:01 +0000975
976 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
977 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
978}
979
980func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
981 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
982 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000983 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
984 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000985 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700986 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000987 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000988 return
989 }
mpagenko5dc85a02021-08-02 12:35:01 +0000990 if abTechProfInstLoadFailed {
Girish Gowdra50e56422021-06-01 16:46:04 -0700991 dh.setDeviceReason(drTechProfileConfigDownloadFailed)
992 dh.stopReconciling(ctx, false)
993 return
994 } else if dh.isSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000995 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
996 }
mpagenko5dc85a02021-08-02 12:35:01 +0000997 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000998 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
999 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001000 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001001 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001002 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001003 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001004}
1005
dbainbri4d3a0dc2020-12-02 00:33:42 +00001006func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
1007 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001008
dbainbri4d3a0dc2020-12-02 00:33:42 +00001009 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001010 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001011 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001012 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001013 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001014 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001015 return
1016 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001017
mpagenko5dc85a02021-08-02 12:35:01 +00001018 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001019 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko5dc85a02021-08-02 12:35:01 +00001020 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001021 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001022 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001023 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001024 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001025 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001026 return
1027 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001028 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001029 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001030 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1031 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001032 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001033 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001034 continue
1035 }
1036 if len(uniData.PersTpPathMap) == 0 {
1037 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
1038 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001039 // It doesn't make sense to configure any flows if no TPs are available
1040 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001041 }
mpagenko5dc85a02021-08-02 12:35:01 +00001042 //release mutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1043 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
1044 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1045 pDevEntry.mutexPersOnuConfig.RUnlock()
1046
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001047 var uniPort *onuUniPort
1048 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +00001049 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001050 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001051 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
1052 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001053 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001054 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001055 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001056 return
1057 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001058 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001059 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001060 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001061 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001062 for _, flowData := range uniData.PersFlowParams {
mpagenko5dc85a02021-08-02 12:35:01 +00001063 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1064 "device-id": dh.deviceID, "uni-id": uniData.PersUniID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001065 // If this is the last flow for the device we need to announce it the waiting
1066 // chReconcilingFlowsFinished channel
1067 if flowsProcessed == len(uniData.PersFlowParams)-1 {
1068 lastFlowToReconcile = true
1069 }
mpagenko01e726e2020-10-23 09:45:29 +00001070 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenko37047052021-07-27 10:01:29 +00001071 dh.lockVlanConfig.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001072 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001073 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +00001074 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +03001075 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001076 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001077 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001078 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001079 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00001080 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +03001081 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001082 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001083 }
1084 }
mpagenko37047052021-07-27 10:01:29 +00001085 dh.lockVlanConfig.Unlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001086 flowsProcessed++
mpagenko5dc85a02021-08-02 12:35:01 +00001087 } //for all flows of this UNI
1088 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
1089 "device-id": dh.deviceID, "uni-id": uniData.PersUniID, "flowsProcessed": flowsProcessed,
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001090 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
1091 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001092 // this can't be used as global finished reconciling flag because
1093 // assumes is getting called before the state machines for the last flow is completed,
1094 // while this is not guaranteed.
1095 //dh.setReconcilingFlows(false)
mpagenko5dc85a02021-08-02 12:35:01 +00001096 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
1097 } // for all UNI entries from sOnuPersistentData
1098 pDevEntry.mutexPersOnuConfig.RUnlock()
1099
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001100 if !flowsFound {
1101 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
1102 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001103 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001104 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001105 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001106 return
1107 }
1108 if dh.isSkipOnuConfigReconciling() {
1109 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001110 }
1111}
1112
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001113func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
1114 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001115 dh.stopReconciling(ctx, true)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001116}
1117
dbainbri4d3a0dc2020-12-02 00:33:42 +00001118func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
1119 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001120
dbainbri4d3a0dc2020-12-02 00:33:42 +00001121 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001122 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001123 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +00001124 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001125 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001126 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001127
1128 // deadline context to ensure completion of background routines waited for
1129 //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 +05301130 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001131 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001132
1133 pDevEntry.resetKvProcessingErrorIndication()
1134
1135 var wg sync.WaitGroup
1136 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001137 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1138 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001139
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001140 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001141 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001142}
1143
mpagenko15ff4a52021-03-02 10:09:20 +00001144//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1145// before this change here return like this was used:
1146// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1147//was and is called in background - error return does not make sense
1148func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1149 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1150 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001151 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001152 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001153 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001154 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301155 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001156 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001157 return
Himani Chawla4d908332020-08-31 12:30:20 +05301158 }
mpagenko01e726e2020-10-23 09:45:29 +00001159
1160 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001161 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001162
Holger Hildebrandt3d77f9c2022-01-12 10:45:13 +00001163 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001164 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
Holger Hildebrandt3d77f9c2022-01-12 10:45:13 +00001165 // do not set the ConnStatus here as it may conflict with the parallel setting from ONU down indication (updateInterface())
1166 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
1167 connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
ozgecanetsiae11479f2020-07-06 09:44:47 +03001168 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001169 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001170 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001171 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001172 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001173 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001174 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001175 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001176 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001177 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1178 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1179 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1180 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001181}
1182
mpagenkoc8bba412021-01-15 15:38:44 +00001183//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko9c225032021-10-15 14:26:49 +00001184// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001185func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1186 apDownloadManager *adapterDownloadManager) error {
1187 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001188 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001189
1190 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001191 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1192 if pDevEntry == nil {
1193 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1194 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1195 }
1196
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001197 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001198 var inactiveImageID uint16
1199 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1200 dh.lockUpgradeFsm.Lock()
mpagenko9c225032021-10-15 14:26:49 +00001201 //lockUpgradeFsm must be release before cancelation as this may implicitly request RemoveOnuUpgradeFsm()
1202 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001203 if dh.pOnuUpradeFsm == nil {
1204 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
mpagenko9c225032021-10-15 14:26:49 +00001205 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001206 if err == nil {
1207 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1208 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1209 "device-id": dh.deviceID, "error": err})
1210 }
1211 } else {
1212 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001213 "device-id": dh.deviceID, "error": err})
1214 }
mpagenko15ff4a52021-03-02 10:09:20 +00001215 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko9c225032021-10-15 14:26:49 +00001216 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001217 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
mpagenko9c225032021-10-15 14:26:49 +00001218 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1219 dh.upgradeCanceled = true
1220 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
mpagenko80622a52021-02-09 16:53:23 +00001221 }
mpagenko9c225032021-10-15 14:26:49 +00001222 //no effort spent anymore for the old API to automatically cancel and restart the download
1223 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001224 }
mpagenko15ff4a52021-03-02 10:09:20 +00001225 } else {
1226 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1227 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001228 }
1229 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001230 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1231 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001232 }
1233 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001234}
1235
mpagenkoc26d4c02021-05-06 14:27:57 +00001236//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1237// after the OnuImage has been downloaded to the adapter, called in background
1238func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
1239 apDownloadManager *fileDownloadManager, aImageIdentifier string) {
1240
1241 var err error
1242 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1243 if pDevEntry == nil {
1244 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1245 return
1246 }
1247
1248 var inactiveImageID uint16
1249 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1250 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
1251 "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
1252 dh.lockUpgradeFsm.Lock()
mpagenko9c225032021-10-15 14:26:49 +00001253 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1254 // but must be still locked at calling createOnuUpgradeFsm
1255 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1256 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1257 if dh.pOnuUpradeFsm != nil {
1258 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1259 // abort the current processing, running upgrades are always aborted by newer request
1260 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.deviceID})
1261 //flush the remove upgradeFsmChan channel
1262 select {
1263 case <-dh.upgradeFsmChan:
1264 logger.Debug(ctx, "flushed-upgrade-fsm-channel")
1265 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001266 }
mpagenko9c225032021-10-15 14:26:49 +00001267 dh.lockUpgradeFsm.Unlock()
1268 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1269 dh.upgradeCanceled = true
1270 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1271 }
1272 select {
1273 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
1274 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.deviceID})
1275 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1276 return
1277 case <-dh.upgradeFsmChan:
1278 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.deviceID})
1279 }
1280 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001281 }
mpagenko9c225032021-10-15 14:26:49 +00001282
1283 //here it can be assumed that no running upgrade processing exists (anymore)
1284 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
1285 // but none yet defined
1286 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1287 dh.lockUpgradeFsm.Unlock()
1288 if err == nil {
1289 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1290 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1291 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
mpagenkoc26d4c02021-05-06 14:27:57 +00001292 "device-id": dh.deviceID, "error": err})
1293 return
1294 }
mpagenko9c225032021-10-15 14:26:49 +00001295 } else {
1296 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1297 "device-id": dh.deviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001298 }
1299 return
1300 }
1301 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1302 "device-id": dh.deviceID, "error": err})
1303}
1304
1305//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001306func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1307 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001308 var err error
1309 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1310 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1311 // 2.) activation of the inactive image
1312
1313 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1314 if pDevEntry == nil {
1315 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001316 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001317 }
1318 dh.lockUpgradeFsm.RLock()
1319 if dh.pOnuUpradeFsm != nil {
1320 dh.lockUpgradeFsm.RUnlock()
1321 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1322 dh.deviceID, dh.deviceID)
1323 if getErr != nil || onuVolthaDevice == nil {
1324 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 +00001325 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001326 }
mpagenko9c225032021-10-15 14:26:49 +00001327 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1328 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.deviceID})
1329 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.deviceID)
1330 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001331 // use the OnuVendor identification from this device for the internal unique name
1332 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko9c225032021-10-15 14:26:49 +00001333 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001334 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001335 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001336 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1337 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001338 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001339 }
mpagenko183647c2021-06-08 15:25:04 +00001340 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1341 "device-id": dh.deviceID, "image-id": imageIdentifier})
mpagenko9c225032021-10-15 14:26:49 +00001342 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001343 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001344 } //else
1345 dh.lockUpgradeFsm.RUnlock()
1346
1347 // 2.) check if requested image-version equals the inactive one and start its activation
1348 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1349 var inactiveImageID uint16
1350 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1351 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1352 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
mpagenko183647c2021-06-08 15:25:04 +00001353 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001354 }
mpagenko9c225032021-10-15 14:26:49 +00001355 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001356 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
mpagenko9c225032021-10-15 14:26:49 +00001357 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001358 if err == nil {
1359 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1360 inactiveImageID, aCommitRequest); err != nil {
1361 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1362 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001363 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001364 }
1365 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1366 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko9c225032021-10-15 14:26:49 +00001367 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001368 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001369 } //else
1370 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1371 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001372 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001373}
1374
1375//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001376func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1377 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001378 var err error
1379 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1380 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1381 // 2.) commitment of the active image
1382
1383 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1384 if pDevEntry == nil {
1385 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001386 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001387 }
1388 dh.lockUpgradeFsm.RLock()
1389 if dh.pOnuUpradeFsm != nil {
1390 dh.lockUpgradeFsm.RUnlock()
1391 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1392 dh.deviceID, dh.deviceID)
1393 if getErr != nil || onuVolthaDevice == nil {
1394 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 +00001395 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001396 }
mpagenko9c225032021-10-15 14:26:49 +00001397 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1398 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.deviceID})
1399 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.deviceID)
1400 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001401 // use the OnuVendor identification from this device for the internal unique name
1402 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko9c225032021-10-15 14:26:49 +00001403 // 1.) check a started upgrade process and relay the commitment request to it
1404 // the running upgrade may be based either on the imageIdentifier (started from download)
1405 // or on the imageVersion (started from pure activation)
1406 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1407 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001408 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1409 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001410 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001411 }
mpagenko183647c2021-06-08 15:25:04 +00001412 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1413 "device-id": dh.deviceID, "image-id": imageIdentifier})
mpagenko9c225032021-10-15 14:26:49 +00001414 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001415 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001416 } //else
1417 dh.lockUpgradeFsm.RUnlock()
1418
mpagenko183647c2021-06-08 15:25:04 +00001419 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001420 var activeImageID uint16
1421 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1422 logger.Errorw(ctx, "get active image failed", log.Fields{
1423 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
mpagenko183647c2021-06-08 15:25:04 +00001424 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001425 }
mpagenko9c225032021-10-15 14:26:49 +00001426 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001427 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
mpagenko9c225032021-10-15 14:26:49 +00001428 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001429 if err == nil {
1430 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1431 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1432 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001433 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001434 }
1435 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1436 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko9c225032021-10-15 14:26:49 +00001437 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001438 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001439 } //else
1440 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1441 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001442 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001443}
1444
mpagenkoaa3afe92021-05-21 16:20:58 +00001445func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko9c225032021-10-15 14:26:49 +00001446 aVersion string) *voltha.ImageState {
1447 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001448 dh.lockUpgradeFsm.RLock()
mpagenko9c225032021-10-15 14:26:49 +00001449 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001450 if dh.pOnuUpradeFsm != nil {
mpagenko9c225032021-10-15 14:26:49 +00001451 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1452 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1453 if aVersion == dh.pLastUpgradeImageState.Version {
1454 pImageState = dh.pLastUpgradeImageState
1455 } else { //state request for an image version different from last processed image version
1456 pImageState = &voltha.ImageState{
1457 Version: aVersion,
1458 //we cannot state something concerning this version
1459 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1460 Reason: voltha.ImageState_NO_ERROR,
1461 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1462 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001463 }
1464 }
mpagenko9c225032021-10-15 14:26:49 +00001465 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001466}
1467
1468func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1469 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1470 pDeviceImageState.DeviceId = dh.deviceID
mpagenko7455fd42021-06-10 16:25:55 +00001471 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001472 dh.lockUpgradeFsm.RLock()
1473 if dh.pOnuUpradeFsm != nil {
mpagenko9c225032021-10-15 14:26:49 +00001474 // so then we cancel the upgrade operation
1475 // but before we still request the actual upgrade states for the direct response
1476 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
mpagenkoaa3afe92021-05-21 16:20:58 +00001477 dh.lockUpgradeFsm.RUnlock()
mpagenko9c225032021-10-15 14:26:49 +00001478 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
mpagenkoaa3afe92021-05-21 16:20:58 +00001479 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
mpagenko9c225032021-10-15 14:26:49 +00001480 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1481 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1482 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
1483 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1484 dh.upgradeCanceled = true
1485 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1486 }
1487 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001488 } else {
1489 dh.lockUpgradeFsm.RUnlock()
mpagenko9c225032021-10-15 14:26:49 +00001490 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1491 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1492 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1493 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1494 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1495 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001496 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1497 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko9c225032021-10-15 14:26:49 +00001498 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1499 //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 +00001500 }
1501}
1502
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001503func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1504
1505 var onuImageStatus *OnuImageStatus
1506
1507 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1508 if pDevEntry != nil {
1509 onuImageStatus = NewOnuImageStatus(pDevEntry)
1510 pDevEntry.mutexOnuImageStatus.Lock()
1511 pDevEntry.pOnuImageStatus = onuImageStatus
1512 pDevEntry.mutexOnuImageStatus.Unlock()
1513
1514 } else {
1515 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1516 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1517 }
1518 images, err := onuImageStatus.getOnuImageStatus(ctx)
1519 pDevEntry.mutexOnuImageStatus.Lock()
1520 pDevEntry.pOnuImageStatus = nil
1521 pDevEntry.mutexOnuImageStatus.Unlock()
1522 return images, err
1523}
1524
Himani Chawla6d2ae152020-09-02 13:11:20 +05301525// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001526// #####################################################################################
1527
1528// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301529// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001530
dbainbri4d3a0dc2020-12-02 00:33:42 +00001531func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1532 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 +00001533}
1534
1535// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001536func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001537
dbainbri4d3a0dc2020-12-02 00:33:42 +00001538 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001539 var err error
1540
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001541 // populate what we know. rest comes later after mib sync
1542 dh.device.Root = false
1543 dh.device.Vendor = "OpenONU"
1544 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001545 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001546 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001547
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001548 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001549
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001550 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001551 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1552 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301553 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001554 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001555 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001556 log.Fields{"device-id": dh.deviceID})
1557 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001558
Himani Chawla4d908332020-08-31 12:30:20 +05301559 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001560 dh.ponPortNumber = dh.device.ParentPortNo
1561
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001562 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1563 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1564 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001565 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001566 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301567 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001568
1569 /*
1570 self._pon = PonPort.create(self, self._pon_port_number)
1571 self._pon.add_peer(self.parent_id, self._pon_port_number)
1572 self.logger.debug('adding-pon-port-to-agent',
1573 type=self._pon.get_port().type,
1574 admin_state=self._pon.get_port().admin_state,
1575 oper_status=self._pon.get_port().oper_status,
1576 )
1577 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001578 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001579 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001580 var ponPortNo uint32 = 1
1581 if dh.ponPortNumber != 0 {
1582 ponPortNo = dh.ponPortNumber
1583 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001584
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001585 pPonPort := &voltha.Port{
1586 PortNo: ponPortNo,
1587 Label: fmt.Sprintf("pon-%d", ponPortNo),
1588 Type: voltha.Port_PON_ONU,
1589 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301590 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001591 PortNo: ponPortNo}}, // Peer port is parent's port number
1592 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001593 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1594 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001595 e.Cancel(err)
1596 return
1597 }
1598 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001599 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001600 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001601 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001602}
1603
1604// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001605func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001606
dbainbri4d3a0dc2020-12-02 00:33:42 +00001607 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001608 var err error
1609 /*
1610 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1611 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1612 return nil
1613 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001614 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1615 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001616 e.Cancel(err)
1617 return
1618 }
1619
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001620 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001621 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001622 // reconcilement will be continued after mib download is done
1623 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001624
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001625 /*
1626 ############################################################################
1627 # Setup Alarm handler
1628 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1629 device.serial_number)
1630 ############################################################################
1631 # Setup PM configuration for this device
1632 # Pass in ONU specific options
1633 kwargs = {
1634 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1635 'heartbeat': self.heartbeat,
1636 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1637 }
1638 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1639 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1640 self.logical_device_id, device.serial_number,
1641 grouped=True, freq_override=False, **kwargs)
1642 pm_config = self._pm_metrics.make_proto()
1643 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1644 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1645 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1646
1647 # Note, ONU ID and UNI intf set in add_uni_port method
1648 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1649 ani_ports=[self._pon])
1650
1651 # Code to Run OMCI Test Action
1652 kwargs_omci_test_action = {
1653 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1654 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1655 }
1656 serial_number = device.serial_number
1657 self._test_request = OmciTestRequest(self.core_proxy,
1658 self.omci_agent, self.device_id,
1659 AniG, serial_number,
1660 self.logical_device_id,
1661 exclusive=False,
1662 **kwargs_omci_test_action)
1663
1664 self.enabled = True
1665 else:
1666 self.logger.info('onu-already-activated')
1667 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001668
dbainbri4d3a0dc2020-12-02 00:33:42 +00001669 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001670}
1671
1672// doStateConnected get the device info and update to voltha core
1673// for comparison of the original method (not that easy to uncomment): compare here:
1674// voltha-openolt-adapter/adaptercore/device_handler.go
1675// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001676func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001677
dbainbri4d3a0dc2020-12-02 00:33:42 +00001678 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301679 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001680 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001681 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001682}
1683
1684// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001685func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001686
dbainbri4d3a0dc2020-12-02 00:33:42 +00001687 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301688 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001689 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001690 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001691
1692 /*
1693 // Synchronous call to update device state - this method is run in its own go routine
1694 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1695 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001696 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 +00001697 return err
1698 }
1699 return nil
1700 */
1701}
1702
1703// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001704func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001705
dbainbri4d3a0dc2020-12-02 00:33:42 +00001706 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001707 var err error
1708
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001709 device := dh.device
1710 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001711 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001712 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001713 e.Cancel(err)
1714 return
1715 }
1716
1717 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001718 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001719 /*
1720 // Update the all ports state on that device to disable
1721 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001722 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001723 return er
1724 }
1725
1726 //Update the device oper state and connection status
1727 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1728 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1729 dh.device = cloned
1730
1731 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001732 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001733 return er
1734 }
1735
1736 //get the child device for the parent device
1737 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1738 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001739 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001740 return err
1741 }
1742 for _, onuDevice := range onuDevices.Items {
1743
1744 // Update onu state as down in onu adapter
1745 onuInd := oop.OnuIndication{}
1746 onuInd.OperState = "down"
1747 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1748 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1749 if er != nil {
1750 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001751 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001752 //Do not return here and continue to process other ONUs
1753 }
1754 }
1755 // * Discovered ONUs entries need to be cleared , since after OLT
1756 // is up, it starts sending discovery indications again* /
1757 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001758 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001759 return nil
1760 */
Himani Chawla4d908332020-08-31 12:30:20 +05301761 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001762 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001763 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001764}
1765
Himani Chawla6d2ae152020-09-02 13:11:20 +05301766// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001767// #################################################################################
1768
1769// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301770// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001771
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001772//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001773func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001774 dh.lockDevice.RLock()
1775 pOnuDeviceEntry := dh.pOnuOmciDevice
1776 if aWait && pOnuDeviceEntry == nil {
1777 //keep the read sema short to allow for subsequent write
1778 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001779 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001780 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1781 // so it might be needed to wait here for that event with some timeout
1782 select {
1783 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001784 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001785 return nil
1786 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001787 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001788 // if written now, we can return the written value without sema
1789 return dh.pOnuOmciDevice
1790 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001791 }
mpagenko3af1f032020-06-10 08:53:41 +00001792 dh.lockDevice.RUnlock()
1793 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001794}
1795
Himani Chawla6d2ae152020-09-02 13:11:20 +05301796//setOnuDeviceEntry sets the ONU device entry within the handler
1797func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001798 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001799 dh.lockDevice.Lock()
1800 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001801 dh.pOnuOmciDevice = apDeviceEntry
1802 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001803 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301804 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001805 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001806}
1807
Himani Chawla6d2ae152020-09-02 13:11:20 +05301808//addOnuDeviceEntry creates a new ONU device or returns the existing
1809func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001810 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001811
dbainbri4d3a0dc2020-12-02 00:33:42 +00001812 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001813 if deviceEntry == nil {
1814 /* costum_me_map in python code seems always to be None,
1815 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1816 /* also no 'clock' argument - usage open ...*/
1817 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001818 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001819 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001820 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301821 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001822 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001823 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001824 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001825 // fire deviceEntry ready event to spread to possibly waiting processing
1826 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001827 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001828 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001829 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001830 }
1831 // might be updated with some error handling !!!
1832 return nil
1833}
1834
dbainbri4d3a0dc2020-12-02 00:33:42 +00001835func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1836 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001837 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1838
1839 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001840
dbainbri4d3a0dc2020-12-02 00:33:42 +00001841 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001842 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001843 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001844 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1845 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001846 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001847 if err := dh.storePersistentData(ctx); err != nil {
1848 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001849 log.Fields{"device-id": dh.deviceID, "err": err})
1850 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001851 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001852 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001853 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001854 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1855 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001856 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001857 }
1858 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001859 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001860 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001861
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001862 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001863 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001864 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001865 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 +00001866 log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001867 dh.stopReconciling(ctx, true)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001868 } else {
1869 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001870 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001871 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001872 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1873 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1874 // 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 +00001875 // 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 +00001876 // so let's just try to keep it simple ...
1877 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001878 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001879 if err != nil || device == nil {
1880 //TODO: needs to handle error scenarios
1881 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1882 return errors.New("Voltha Device not found")
1883 }
1884 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001885
dbainbri4d3a0dc2020-12-02 00:33:42 +00001886 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001887 return err
mpagenko3af1f032020-06-10 08:53:41 +00001888 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001889
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001890 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001891
1892 /* this might be a good time for Omci Verify message? */
1893 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001894 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001895 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001896 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001897 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001898
1899 /* give the handler some time here to wait for the OMCi verification result
1900 after Timeout start and try MibUpload FSM anyway
1901 (to prevent stopping on just not supported OMCI verification from ONU) */
1902 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001903 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001904 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001905 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001906 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001907 }
1908
1909 /* In py code it looks earlier (on activate ..)
1910 # Code to Run OMCI Test Action
1911 kwargs_omci_test_action = {
1912 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1913 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1914 }
1915 serial_number = device.serial_number
1916 self._test_request = OmciTestRequest(self.core_proxy,
1917 self.omci_agent, self.device_id,
1918 AniG, serial_number,
1919 self.logical_device_id,
1920 exclusive=False,
1921 **kwargs_omci_test_action)
1922 ...
1923 # Start test requests after a brief pause
1924 if not self._test_request_started:
1925 self._test_request_started = True
1926 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1927 reactor.callLater(tststart, self._test_request.start_collector)
1928
1929 */
1930 /* which is then: in omci_test_request.py : */
1931 /*
1932 def start_collector(self, callback=None):
1933 """
1934 Start the collection loop for an adapter if the frequency > 0
1935
1936 :param callback: (callable) Function to call to collect PM data
1937 """
1938 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1939 if callback is None:
1940 callback = self.perform_test_omci
1941
1942 if self.lc is None:
1943 self.lc = LoopingCall(callback)
1944
1945 if self.default_freq > 0:
1946 self.lc.start(interval=self.default_freq / 10)
1947
1948 def perform_test_omci(self):
1949 """
1950 Perform the initial test request
1951 """
1952 ani_g_entities = self._device.configuration.ani_g_entities
1953 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1954 is not None else None
1955 self._entity_id = ani_g_entities_ids[0]
1956 self.logger.info('perform-test', entity_class=self._entity_class,
1957 entity_id=self._entity_id)
1958 try:
1959 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1960 result = yield self._device.omci_cc.send(frame)
1961 if not result.fields['omci_message'].fields['success_code']:
1962 self.logger.info('Self-Test Submitted Successfully',
1963 code=result.fields[
1964 'omci_message'].fields['success_code'])
1965 else:
1966 raise TestFailure('Test Failure: {}'.format(
1967 result.fields['omci_message'].fields['success_code']))
1968 except TimeoutError as e:
1969 self.deferred.errback(failure.Failure(e))
1970
1971 except Exception as e:
1972 self.logger.exception('perform-test-Error', e=e,
1973 class_id=self._entity_class,
1974 entity_id=self._entity_id)
1975 self.deferred.errback(failure.Failure(e))
1976
1977 */
1978
1979 // PM related heartbeat??? !!!TODO....
1980 //self._heartbeat.enabled = True
1981
mpagenko1cc3cb42020-07-27 15:24:38 +00001982 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1983 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1984 * 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 +05301985 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001986 */
1987 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001988 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001989 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001990 if pMibUlFsm.Is(ulStDisabled) {
1991 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001992 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 +00001993 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301994 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001995 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301996 //Determine ONU status and start/re-start MIB Synchronization tasks
1997 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001998 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301999 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002000 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 +00002001 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002002 }
Himani Chawla4d908332020-08-31 12:30:20 +05302003 } else {
2004 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002005 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 +00002006 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302007 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002008 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002009 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002010 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002011 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002012 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002013 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002014 }
2015 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002016 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002017 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002018 }
2019 return nil
2020}
2021
dbainbri4d3a0dc2020-12-02 00:33:42 +00002022func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00002023 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002024 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002025 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002026 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002027
mpagenko900ee4b2020-10-12 11:56:34 +00002028 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2029 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2030 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002031 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002032 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00002033 log.Fields{"device-id": dh.deviceID, "error": err})
2034 // abort: system behavior is just unstable ...
2035 return err
2036 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002037 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002038 _ = 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 +00002039
2040 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
Holger Hildebrandt3d77f9c2022-01-12 10:45:13 +00002041 //stop the device entry to allow for all system event transfers again
dbainbri4d3a0dc2020-12-02 00:33:42 +00002042 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002043 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002044 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002045 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002046 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002047 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002048
2049 //TODO!!! remove existing traffic profiles
2050 /* from py code, if TP's exist, remove them - not yet implemented
2051 self._tp = dict()
2052 # Let TP download happen again
2053 for uni_id in self._tp_service_specific_task:
2054 self._tp_service_specific_task[uni_id].clear()
2055 for uni_id in self._tech_profile_download_done:
2056 self._tech_profile_download_done[uni_id].clear()
2057 */
2058
dbainbri4d3a0dc2020-12-02 00:33:42 +00002059 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002060
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002061 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002062
dbainbri4d3a0dc2020-12-02 00:33:42 +00002063 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002064 // abort: system behavior is just unstable ...
2065 return err
2066 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002067 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002068 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002069 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00002070 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002071 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002072 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00002073 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002074 // abort: system behavior is just unstable ...
2075 return err
2076 }
2077 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002078 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002079 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002080 return nil
2081}
2082
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002083func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002084 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2085 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2086 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2087 // and using the stop/reset event should never harm
2088
dbainbri4d3a0dc2020-12-02 00:33:42 +00002089 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002090 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002091 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002092 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2093 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002094 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002095 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002096 }
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002097 pDevEntry.mutexOnuImageStatus.RLock()
2098 if pDevEntry.pOnuImageStatus != nil {
2099 pDevEntry.pOnuImageStatus.CancelProcessing(ctx)
2100 }
2101 pDevEntry.mutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002102
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002103 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002104 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002105 }
2106 //MibDownload may run
2107 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2108 if pMibDlFsm != nil {
2109 _ = pMibDlFsm.Event(dlEvReset)
2110 }
2111 //port lock/unlock FSM's may be active
2112 if dh.pUnlockStateFsm != nil {
2113 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2114 }
2115 if dh.pLockStateFsm != nil {
2116 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2117 }
2118 //techProfile related PonAniConfigFsm FSM may be active
2119 if dh.pOnuTP != nil {
2120 // should always be the case here
2121 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
2122 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08002123 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00002124 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002125 }
mpagenko900ee4b2020-10-12 11:56:34 +00002126 }
2127 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002128 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002129 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00002130 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
2131 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002132 dh.lockVlanConfig.RUnlock()
2133 //reset of all Fsm is always accompanied by global persistency data removal
2134 // no need to remove specific data
Holger Hildebrandt72eaab72021-11-05 08:54:59 +00002135 pVlanFilterFsm.RequestClearPersistency(ctx, false)
mpagenko7d6bb022021-03-11 15:07:55 +00002136 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002137 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002138 } else {
2139 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002140 }
2141 }
2142 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002143 if dh.getCollectorIsRunning() {
2144 // Stop collector routine
2145 dh.stopCollector <- true
2146 }
Himani Chawla1472c682021-03-17 17:11:14 +05302147 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302148 dh.stopAlarmManager <- true
2149 }
2150
mpagenko80622a52021-02-09 16:53:23 +00002151 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00002152 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002153 dh.lockUpgradeFsm.RLock()
mpagenko9c225032021-10-15 14:26:49 +00002154 lopOnuUpradeFsm := dh.pOnuUpradeFsm
2155 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002156 dh.lockUpgradeFsm.RUnlock()
mpagenko9c225032021-10-15 14:26:49 +00002157 if lopOnuUpradeFsm != nil {
2158 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2159 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2160 // (even though it may also run into direct cancellation, a bit hard to verify here)
2161 // so don't set 'dh.upgradeCanceled = true' here!
2162 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2163 }
2164 }
mpagenko80622a52021-02-09 16:53:23 +00002165
mpagenko7d6bb022021-03-11 15:07:55 +00002166 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002167 return nil
2168}
2169
dbainbri4d3a0dc2020-12-02 00:33:42 +00002170func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2171 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 +05302172
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002173 // store persistent data collected during MIB upload processing
2174 if err := dh.storePersistentData(ctx); err != nil {
2175 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2176 log.Fields{"device-id": dh.deviceID, "err": err})
2177 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002178 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002179 dh.addAllUniPorts(ctx)
2180
mpagenkoa40e99a2020-11-17 13:50:39 +00002181 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2182 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2183 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2184 * disable/enable toggling here to allow traffic
2185 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2186 * like the py comment says:
2187 * # start by locking all the unis till mib sync and initial mib is downloaded
2188 * # this way we can capture the port down/up events when we are ready
2189 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302190
mpagenkoa40e99a2020-11-17 13:50:39 +00002191 // Init Uni Ports to Admin locked state
2192 // *** should generate UniLockStateDone event *****
2193 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002194 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002195 } else { //LockStateFSM already init
2196 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002197 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002198 }
2199}
2200
dbainbri4d3a0dc2020-12-02 00:33:42 +00002201func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2202 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302203 /* Mib download procedure -
2204 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2205 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002206 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002207 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002208 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002209 return
2210 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302211 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2212 if pMibDlFsm != nil {
2213 if pMibDlFsm.Is(dlStDisabled) {
2214 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002215 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 +05302216 // maybe try a FSM reset and then again ... - TODO!!!
2217 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002218 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302219 // maybe use more specific states here for the specific download steps ...
2220 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002221 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302222 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002223 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302224 //Begin MIB data download (running autonomously)
2225 }
2226 }
2227 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002228 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002229 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302230 // maybe try a FSM reset and then again ... - TODO!!!
2231 }
2232 /***** Mib download started */
2233 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002234 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302235 }
2236}
2237
dbainbri4d3a0dc2020-12-02 00:33:42 +00002238func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2239 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302240 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002241 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002242 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002243 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002244 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2245 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2246 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2247 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002248 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302249 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
2250 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002251 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302252 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002253 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302254 }
2255 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002256 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302257 log.Fields{"device-id": dh.deviceID})
2258 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002259 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002260
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002261 if !dh.getCollectorIsRunning() {
2262 // Start PM collector routine
2263 go dh.startCollector(ctx)
2264 }
2265 if !dh.getAlarmManagerIsRunning(ctx) {
2266 go dh.startAlarmManager(ctx)
2267 }
2268
Girish Gowdrae0140f02021-02-02 16:55:09 -08002269 // Initialize classical L2 PM Interval Counters
2270 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2271 // There is no way we should be landing here, but if we do then
2272 // there is nothing much we can do about this other than log error
2273 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2274 }
2275
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002276 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002277
2278 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2279 if pDevEntry == nil {
2280 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2281 return
2282 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002283 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002284 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002285 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002286 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2287 log.Fields{"device-id": dh.deviceID})
2288 go dh.reconcileDeviceTechProf(ctx)
2289 // reconcilement will be continued after ani config is done
2290 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002291 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002292 // *** should generate UniUnlockStateDone event *****
2293 if dh.pUnlockStateFsm == nil {
2294 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2295 } else { //UnlockStateFSM already init
2296 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2297 dh.runUniLockFsm(ctx, false)
2298 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302299 }
2300}
2301
dbainbri4d3a0dc2020-12-02 00:33:42 +00002302func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2303 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302304
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002305 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002306 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002307 raisedTs := time.Now().Unix()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002308 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2309 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002310 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002311 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002312 return
2313 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002314 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002315 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002316 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002317 if err := dh.storePersistentData(ctx); err != nil {
2318 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002319 log.Fields{"device-id": dh.deviceID, "err": err})
2320 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302321 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002322 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 +05302323 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002324 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002325 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302326 }
2327}
2328
dbainbri4d3a0dc2020-12-02 00:33:42 +00002329func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
Holger Hildebrandt3d77f9c2022-01-12 10:45:13 +00002330 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
mpagenko900ee4b2020-10-12 11:56:34 +00002331 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
Holger Hildebrandt3d77f9c2022-01-12 10:45:13 +00002332 // disable device should have no impact on ConnStatus
2333 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
2334 connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
2335 voltha.OperStatus_UNKNOWN); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002336 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002337 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002338 }
2339
dbainbri4d3a0dc2020-12-02 00:33:42 +00002340 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002341 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002342 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002343
2344 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002345 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002346
dbainbri4d3a0dc2020-12-02 00:33:42 +00002347 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002348 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002349 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002350 return
2351 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002352 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002353 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002354 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002355 if err := dh.storePersistentData(ctx); err != nil {
2356 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002357 log.Fields{"device-id": dh.deviceID, "err": err})
2358 }
mpagenko900ee4b2020-10-12 11:56:34 +00002359}
2360
dbainbri4d3a0dc2020-12-02 00:33:42 +00002361func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2362 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002363 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002364 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002365 voltha.OperStatus_ACTIVE); err != nil {
2366 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002367 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002368 }
2369
dbainbri4d3a0dc2020-12-02 00:33:42 +00002370 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002371 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002372 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002373 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002374
2375 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002376 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002377
dbainbri4d3a0dc2020-12-02 00:33:42 +00002378 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002379 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002380 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002381 return
2382 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002383 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002384 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002385 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002386 if err := dh.storePersistentData(ctx); err != nil {
2387 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002388 log.Fields{"device-id": dh.deviceID, "err": err})
2389 }
mpagenko900ee4b2020-10-12 11:56:34 +00002390}
2391
Holger Hildebrandtda15a092022-01-07 15:30:49 +00002392func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2393 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2394 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.deviceID})
2395 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
2396 voltha.OperStatus_FAILED); err != nil {
2397 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
2398 }
2399}
2400
dbainbri4d3a0dc2020-12-02 00:33:42 +00002401func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002402 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002403 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002404 // attention: the device reason update is done based on ONU-UNI-Port related activity
2405 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002406 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002407 // 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 +00002408 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302409 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002410 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002411 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002412 }
2413 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002414 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002415 // attention: the device reason update is done based on ONU-UNI-Port related activity
2416 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002417 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002418 // 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 +00002419 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002420 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002421 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302422}
2423
dbainbri4d3a0dc2020-12-02 00:33:42 +00002424func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2425 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002426 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302427 // attention: the device reason update is done based on ONU-UNI-Port related activity
2428 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302429
mpagenkof1fc3862021-02-16 10:09:52 +00002430 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002431 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002432 // which may be the case from some previous actvity on another UNI Port of the ONU
2433 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002434 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2435 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002436 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002437 }
2438 }
2439 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002440 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002441 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002442 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002443 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302444 }
mpagenkof1fc3862021-02-16 10:09:52 +00002445
2446 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2447 //events that request KvStore write
2448 if err := dh.storePersistentData(ctx); err != nil {
2449 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2450 log.Fields{"device-id": dh.deviceID, "err": err})
2451 }
2452 } else {
2453 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2454 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002455 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302456}
2457
Himani Chawla6d2ae152020-09-02 13:11:20 +05302458//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002459func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302460 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002461 case MibDatabaseSync:
2462 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002463 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002464 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002465 case UniLockStateDone:
2466 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002467 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002468 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002469 case MibDownloadDone:
2470 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002471 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002472 }
2473 case UniUnlockStateDone:
2474 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002475 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002476 }
mpagenko900ee4b2020-10-12 11:56:34 +00002477 case UniEnableStateDone:
2478 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002479 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002480 }
Holger Hildebrandtda15a092022-01-07 15:30:49 +00002481 case UniEnableStateFailed:
2482 {
2483 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2484 }
mpagenko900ee4b2020-10-12 11:56:34 +00002485 case UniDisableStateDone:
2486 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002487 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002488 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002489 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002490 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002491 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002492 }
mpagenkof1fc3862021-02-16 10:09:52 +00002493 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002494 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002495 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002496 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002497 default:
2498 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002499 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002500 }
2501 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002502}
2503
dbainbri4d3a0dc2020-12-02 00:33:42 +00002504func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002505 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002506 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302507 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002508 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002509 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002510 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302511 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002512 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002513 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002514 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002515 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002516 //store UniPort with the System-PortNumber key
2517 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002518 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002519 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002520 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2521 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002522 } //error logging already within UniPort method
2523 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002524 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002525 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002526 }
2527 }
2528}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002529
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002530func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2531 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2532 if pDevEntry == nil {
2533 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2534 return
2535 }
2536 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2537 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2538 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2539 for _, mgmtEntityID := range pptpInstKeys {
2540 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2541 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2542 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2543 i++
2544 }
2545 } else {
2546 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2547 }
2548 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2549 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2550 for _, mgmtEntityID := range veipInstKeys {
2551 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2552 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2553 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2554 i++
2555 }
2556 } else {
2557 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2558 }
2559 if i == 0 {
2560 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2561 }
2562}
2563
mpagenko3af1f032020-06-10 08:53:41 +00002564// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002565func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002566 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302567 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002568 // with following remark:
2569 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2570 // # load on the core
2571
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002572 // 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 +00002573
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002574 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002575 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002576 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002577 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302578 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002579 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002580 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002581 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 +00002582 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002583 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002584 }
mpagenko3af1f032020-06-10 08:53:41 +00002585 }
2586 }
2587}
2588
2589// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002590func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002591 // compare enableUniPortStateUpdate() above
2592 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2593 for uniNo, uniPort := range dh.uniEntityMap {
2594 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002595
2596 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002597 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302598 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002599 if !dh.isReconciling() {
2600 //maybe also use getter functions on uniPort - perhaps later ...
2601 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2602 } else {
2603 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2604 }
2605
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002606 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002607 }
2608}
2609
2610// ONU_Active/Inactive announcement on system KAFKA bus
2611// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002612func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002613 var de voltha.DeviceEvent
2614 eventContext := make(map[string]string)
2615 //Populating event context
2616 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002617 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002618 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002619 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302620 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002621 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 +00002622 }
2623 oltSerialNumber := parentDevice.SerialNumber
2624
2625 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2626 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2627 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302628 eventContext["olt-serial-number"] = oltSerialNumber
2629 eventContext["device-id"] = aDeviceID
2630 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002631 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
2632 if deviceEntry := dh.getOnuDeviceEntry(ctx, false); deviceEntry != nil {
2633 deviceEntry.mutexPersOnuConfig.RLock()
2634 eventContext["equipment-id"] = deviceEntry.sOnuPersistentData.PersEquipmentID
2635 deviceEntry.mutexPersOnuConfig.RUnlock()
2636 eventContext["software-version"] = deviceEntry.getActiveImageVersion(ctx)
2637 deviceEntry.mutexPersOnuConfig.RLock()
2638 eventContext["vendor"] = deviceEntry.sOnuPersistentData.PersVendorID
2639 deviceEntry.mutexPersOnuConfig.RUnlock()
2640 eventContext["inactive-software-version"] = deviceEntry.getInactiveImageVersion(ctx)
2641 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2642 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2643 } else {
2644 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2645 log.Fields{"device-id": aDeviceID})
2646 return
2647 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002648
2649 /* Populating device event body */
2650 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302651 de.ResourceId = aDeviceID
2652 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002653 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2654 de.Description = fmt.Sprintf("%s Event - %s - %s",
2655 cEventObjectType, cOnuActivatedEvent, "Raised")
2656 } else {
2657 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2658 de.Description = fmt.Sprintf("%s Event - %s - %s",
2659 cEventObjectType, cOnuActivatedEvent, "Cleared")
2660 }
2661 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002662 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2663 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302664 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002665 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002666 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302667 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002668}
2669
Himani Chawla4d908332020-08-31 12:30:20 +05302670// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002671func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002672 chLSFsm := make(chan Message, 2048)
2673 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302674 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002675 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002676 sFsmName = "LockStateFSM"
2677 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002678 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002679 sFsmName = "UnLockStateFSM"
2680 }
mpagenko3af1f032020-06-10 08:53:41 +00002681
dbainbri4d3a0dc2020-12-02 00:33:42 +00002682 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002683 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002684 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002685 return
2686 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002687 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002688 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002689 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302690 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002691 dh.pLockStateFsm = pLSFsm
2692 } else {
2693 dh.pUnlockStateFsm = pLSFsm
2694 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002695 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002696 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002697 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002698 }
2699}
2700
2701// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002702func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002703 /* Uni Port lock/unlock procedure -
2704 ***** should run via 'adminDone' state and generate the argument requested event *****
2705 */
2706 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302707 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002708 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2709 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2710 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002711 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302712 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002713 }
2714 } else {
2715 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2716 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2717 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002718 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302719 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002720 }
2721 }
2722 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002723 if pLSStatemachine.Is(uniStDisabled) {
2724 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002725 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002726 // maybe try a FSM reset and then again ... - TODO!!!
2727 } else {
2728 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002729 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002730 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002731 }
2732 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002733 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002734 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002735 // maybe try a FSM reset and then again ... - TODO!!!
2736 }
2737 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002738 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002739 // maybe try a FSM reset and then again ... - TODO!!!
2740 }
2741}
2742
mpagenko80622a52021-02-09 16:53:23 +00002743// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko9c225032021-10-15 14:26:49 +00002744// precondition: lockUpgradeFsm is already locked from caller of this function
mpagenko15ff4a52021-03-02 10:09:20 +00002745func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002746 //in here lockUpgradeFsm is already locked
2747 chUpgradeFsm := make(chan Message, 2048)
2748 var sFsmName = "OnuSwUpgradeFSM"
2749 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002750 if apDevEntry.PDevOmciCC == nil {
2751 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2752 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002753 }
mpagenko15ff4a52021-03-02 10:09:20 +00002754 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002755 sFsmName, chUpgradeFsm)
2756 if dh.pOnuUpradeFsm != nil {
2757 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2758 if pUpgradeStatemachine != nil {
2759 if pUpgradeStatemachine.Is(upgradeStDisabled) {
2760 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2761 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2762 // maybe try a FSM reset and then again ... - TODO!!!
2763 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2764 }
mpagenko9c225032021-10-15 14:26:49 +00002765 /***** Upgrade FSM started */
2766 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2767 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
2768 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2769 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002770 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2771 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2772 } else {
2773 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2774 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2775 // maybe try a FSM reset and then again ... - TODO!!!
2776 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2777 }
2778 } else {
2779 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2780 // maybe try a FSM reset and then again ... - TODO!!!
2781 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2782 }
2783 } else {
2784 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2785 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2786 }
2787 return nil
2788}
2789
2790// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
mpagenko9c225032021-10-15 14:26:49 +00002791func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002792 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2793 "device-id": dh.deviceID})
2794 dh.lockUpgradeFsm.Lock()
mpagenko9c225032021-10-15 14:26:49 +00002795 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2796 dh.upgradeCanceled = false //cancelation done
2797 dh.pLastUpgradeImageState = apImageState
2798 dh.lockUpgradeFsm.Unlock()
2799 //signal upgradeFsm removed using non-blocking channel send
2800 select {
2801 case dh.upgradeFsmChan <- struct{}{}:
2802 default:
2803 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
2804 "device-id": dh.deviceID})
2805 }
mpagenko80622a52021-02-09 16:53:23 +00002806}
2807
mpagenko15ff4a52021-03-02 10:09:20 +00002808// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2809func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2810 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2811 if pDevEntry == nil {
2812 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2813 return
2814 }
2815
2816 dh.lockUpgradeFsm.RLock()
mpagenko9c225032021-10-15 14:26:49 +00002817 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00002818 if dh.pOnuUpradeFsm != nil {
mpagenko9c225032021-10-15 14:26:49 +00002819 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
2820 dh.lockUpgradeFsm.RUnlock()
2821 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.deviceID})
2822 return
2823 }
mpagenko15ff4a52021-03-02 10:09:20 +00002824 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2825 if pUpgradeStatemachine != nil {
2826 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2827 // (some manual forced commit could do without)
mpagenko1f8e8822021-06-25 14:10:21 +00002828 upgradeState := pUpgradeStatemachine.Current()
2829 if (upgradeState == upgradeStWaitForCommit) ||
2830 (upgradeState == upgradeStRequestingActivate) {
2831 // also include upgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00002832 // 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 +00002833 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00002834 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
2835 if errImg != nil {
mpagenko9c225032021-10-15 14:26:49 +00002836 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00002837 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
2838 log.Fields{"device-id": dh.deviceID})
mpagenko9c225032021-10-15 14:26:49 +00002839 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2840 dh.upgradeCanceled = true
2841 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2842 }
mpagenko15ff4a52021-03-02 10:09:20 +00002843 return
2844 }
mpagenko9c225032021-10-15 14:26:49 +00002845 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00002846 if activeImageID == dh.pOnuUpradeFsm.inactiveImageMeID {
2847 if (upgradeState == upgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
2848 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
2849 if err := pUpgradeStatemachine.Event(upgradeEvActivationDone); err != nil {
2850 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
2851 return
2852 }
2853 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
2854 "state": upgradeState, "device-id": dh.deviceID})
2855 } else {
2856 //FSM in waitForCommit or (upgradeStRequestingActivate [lost ActivateResp] and commit allowed)
2857 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2858 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2859 return
2860 }
2861 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2862 "state": upgradeState, "device-id": dh.deviceID})
2863 }
2864 } else {
2865 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit/on ActivateResponse, but load did not start with expected image Id",
2866 log.Fields{"device-id": dh.deviceID})
mpagenko9c225032021-10-15 14:26:49 +00002867 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2868 dh.upgradeCanceled = true
2869 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2870 }
mpagenko1f8e8822021-06-25 14:10:21 +00002871 }
mpagenko15ff4a52021-03-02 10:09:20 +00002872 return
2873 }
mpagenko9c225032021-10-15 14:26:49 +00002874 dh.lockUpgradeFsm.RUnlock()
2875 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2876 log.Fields{"device-id": dh.deviceID})
2877 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2878 dh.upgradeCanceled = true
2879 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2880 }
2881 return
2882 }
2883 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2884 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2885 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2886 if dh.pOnuUpradeFsm.inactiveImageMeID == activeImageID {
2887 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2888 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2889 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00002890 }
mpagenko15ff4a52021-03-02 10:09:20 +00002891 }
2892 }
2893 } else {
2894 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2895 }
mpagenko9c225032021-10-15 14:26:49 +00002896 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00002897}
2898
Himani Chawla6d2ae152020-09-02 13:11:20 +05302899//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002900func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002901
2902 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002903 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07002904 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00002905 kvbackend := &db.Backend{
2906 Client: dh.pOpenOnuAc.kvClient,
2907 StoreType: dh.pOpenOnuAc.KVStoreType,
2908 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002909 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002910 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2911 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002912
mpagenkoaf801632020-07-03 10:00:42 +00002913 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002914}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002915func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302916 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002917
mpagenkodff5dda2020-08-28 11:52:01 +00002918 for _, field := range flow.GetOfbFields(apFlowItem) {
2919 switch field.Type {
2920 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2921 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002922 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002923 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2924 }
mpagenko01e726e2020-10-23 09:45:29 +00002925 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002926 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2927 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302928 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002929 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302930 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2931 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002932 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2933 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002934 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2935 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302936 return
mpagenkodff5dda2020-08-28 11:52:01 +00002937 }
2938 }
mpagenko01e726e2020-10-23 09:45:29 +00002939 */
mpagenkodff5dda2020-08-28 11:52:01 +00002940 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2941 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302942 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002943 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302944 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002945 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302946 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002947 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002948 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302949 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002950 }
2951 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2952 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302953 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002954 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002955 "PCP": loAddPcp})
2956 }
2957 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2958 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002959 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002960 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2961 }
2962 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2963 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002964 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002965 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2966 }
2967 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2968 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002969 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002970 "IPv4-DST": field.GetIpv4Dst()})
2971 }
2972 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2973 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002974 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002975 "IPv4-SRC": field.GetIpv4Src()})
2976 }
2977 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2978 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002979 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002980 "Metadata": field.GetTableMetadata()})
2981 }
2982 /*
2983 default:
2984 {
2985 //all other entires ignored
2986 }
2987 */
2988 }
2989 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302990}
mpagenkodff5dda2020-08-28 11:52:01 +00002991
dbainbri4d3a0dc2020-12-02 00:33:42 +00002992func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002993 for _, action := range flow.GetActions(apFlowItem) {
2994 switch action.Type {
2995 /* not used:
2996 case of.OfpActionType_OFPAT_OUTPUT:
2997 {
mpagenko01e726e2020-10-23 09:45:29 +00002998 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002999 "Output": action.GetOutput()})
3000 }
3001 */
3002 case of.OfpActionType_OFPAT_PUSH_VLAN:
3003 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003004 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003005 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3006 }
3007 case of.OfpActionType_OFPAT_SET_FIELD:
3008 {
3009 pActionSetField := action.GetSetField()
3010 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003011 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003012 "OxcmClass": pActionSetField.Field.OxmClass})
3013 }
3014 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303015 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00003016 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303017 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003018 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303019 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00003020 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303021 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003022 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003023 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003024 "Type": pActionSetField.Field.GetOfbField().Type})
3025 }
3026 }
3027 /*
3028 default:
3029 {
3030 //all other entires ignored
3031 }
3032 */
3033 }
3034 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303035}
3036
3037//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
ozgecanetsia82b91a62021-05-21 18:54:49 +03003038func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort,
3039 apFlowMetaData *voltha.FlowMetadata) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05303040 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3041 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
3042 var loAddPcp, loSetPcp uint8
3043 var loIPProto uint32
3044 /* the TechProfileId is part of the flow Metadata - compare also comment within
3045 * OLT-Adapter:openolt_flowmgr.go
3046 * Metadata 8 bytes:
3047 * Most Significant 2 Bytes = Inner VLAN
3048 * Next 2 Bytes = Tech Profile ID(TPID)
3049 * Least Significant 4 Bytes = Port ID
3050 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3051 * subscriber related flows.
3052 */
3053
dbainbri4d3a0dc2020-12-02 00:33:42 +00003054 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303055 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003056 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05303057 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003058 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303059 }
mpagenko551a4d42020-12-08 18:09:20 +00003060 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003061 loCookie := apFlowItem.GetCookie()
3062 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00003063 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003064 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05303065
dbainbri4d3a0dc2020-12-02 00:33:42 +00003066 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003067 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303068 if loIPProto == 2 {
3069 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3070 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003071 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
3072 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303073 return nil
3074 }
mpagenko01e726e2020-10-23 09:45:29 +00003075 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003076 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003077
3078 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003079 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003080 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
3081 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3082 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3083 //TODO!!: Use DeviceId within the error response to rwCore
3084 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00003085 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003086 }
3087 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003088 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003089 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3090 } else {
3091 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3092 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3093 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303094 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003095 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003096 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003097 }
mpagenko9a304ea2020-12-16 15:54:01 +00003098
ozgecanetsia82b91a62021-05-21 18:54:49 +03003099 var meter *voltha.OfpMeterConfig
3100 if apFlowMetaData != nil {
3101 meter = apFlowMetaData.Meters[0]
3102 }
mpagenko2f487262021-08-23 15:59:06 +00003103 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3104 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3105 // when different rules are requested concurrently for the same uni
3106 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3107 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3108 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
3109 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 +05303110 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenko2f487262021-08-23 15:59:06 +00003111 //SetUniFlowParams() may block on some rule that is suspended-to-add
3112 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
mpagenkof1fc3862021-02-16 10:09:52 +00003113 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003114 loMatchVlan, loSetVlan, loSetPcp, false, meter)
mpagenko2f487262021-08-23 15:59:06 +00003115 dh.lockVlanConfig.RUnlock()
3116 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
mpagenkof1fc3862021-02-16 10:09:52 +00003117 return err
mpagenkodff5dda2020-08-28 11:52:01 +00003118 }
mpagenko2f487262021-08-23 15:59:06 +00003119 dh.lockVlanConfig.RUnlock()
3120 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko37047052021-07-27 10:01:29 +00003121 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003122 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false, meter)
mpagenko37047052021-07-27 10:01:29 +00003123 dh.lockVlanConfig.Unlock()
mpagenko2f487262021-08-23 15:59:06 +00003124 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
mpagenko37047052021-07-27 10:01:29 +00003125 return err
mpagenko01e726e2020-10-23 09:45:29 +00003126}
3127
3128//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00003129func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00003130 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3131 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3132 //no extra check is done on the rule parameters
3133 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3134 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3135 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3136 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003137 // - 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 +00003138 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003139 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003140
3141 /* TT related temporary workaround - should not be needed anymore
3142 for _, field := range flow.GetOfbFields(apFlowItem) {
3143 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3144 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00003145 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003146 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3147 if loIPProto == 2 {
3148 // 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 +00003149 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00003150 log.Fields{"device-id": dh.deviceID})
3151 return nil
3152 }
3153 }
3154 } //for all OfbFields
3155 */
3156
mpagenko9a304ea2020-12-16 15:54:01 +00003157 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003158 dh.lockVlanConfig.RLock()
3159 defer dh.lockVlanConfig.RUnlock()
mpagenko2f487262021-08-23 15:59:06 +00003160 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.deviceID, "uniID": apUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +00003161 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003162 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00003163 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003164 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00003165 log.Fields{"device-id": dh.deviceID})
3166 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003167 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00003168 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00003169
mpagenko01e726e2020-10-23 09:45:29 +00003170 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00003171}
3172
Himani Chawla26e555c2020-08-31 12:30:20 +05303173// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003174// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko37047052021-07-27 10:01:29 +00003175// precondition: dh.lockVlanConfig is locked by the caller!
mpagenko551a4d42020-12-08 18:09:20 +00003176func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003177 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
mpagenkodff5dda2020-08-28 11:52:01 +00003178 chVlanFilterFsm := make(chan Message, 2048)
3179
dbainbri4d3a0dc2020-12-02 00:33:42 +00003180 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003181 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003182 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303183 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003184 }
3185
dbainbri4d3a0dc2020-12-02 00:33:42 +00003186 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00003187 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003188 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter)
mpagenkodff5dda2020-08-28 11:52:01 +00003189 if pVlanFilterFsm != nil {
mpagenko37047052021-07-27 10:01:29 +00003190 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3191 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Himani Chawla26e555c2020-08-31 12:30:20 +05303192 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003193 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3194 if pVlanFilterStatemachine != nil {
3195 if pVlanFilterStatemachine.Is(vlanStDisabled) {
3196 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003197 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05303198 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003199 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303200 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003201 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05303202 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3203 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003204 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003205 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003206 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303207 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003208 }
3209 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003210 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003211 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303212 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003213 }
3214 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003215 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003216 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05303217 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003218 }
3219 return nil
3220}
3221
mpagenkofc4f56e2020-11-04 17:17:49 +00003222//VerifyVlanConfigRequest checks on existence of a given uniPort
3223// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003224func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003225 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
3226 var pCurrentUniPort *onuUniPort
3227 for _, uniPort := range dh.uniEntityMap {
3228 // only if this port is validated for operState transfer
3229 if uniPort.uniID == uint8(aUniID) {
3230 pCurrentUniPort = uniPort
3231 break //found - end search loop
3232 }
3233 }
3234 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003235 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00003236 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
3237 return
3238 }
mpagenko551a4d42020-12-08 18:09:20 +00003239 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003240}
3241
mpagenkodff5dda2020-08-28 11:52:01 +00003242//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00003243func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003244 //TODO!! verify and start pending flow configuration
3245 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3246 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003247
3248 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303249 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003250 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003251 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
3252 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3253 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003254 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandt72eaab72021-11-05 08:54:59 +00003255 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
mpagenko551a4d42020-12-08 18:09:20 +00003256 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
3257 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
3258 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3259 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3260 } else {
3261 /***** UniVlanConfigFsm continued */
3262 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
3263 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3264 "UniPort": apUniPort.portNo})
3265 }
3266 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
3267 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
3268 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3269 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3270 } else {
3271 /***** UniVlanConfigFsm continued */
3272 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3273 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3274 "UniPort": apUniPort.portNo})
3275 }
mpagenkodff5dda2020-08-28 11:52:01 +00003276 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003277 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3278 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003279 "UniPort": apUniPort.portNo})
3280 }
3281 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003282 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3283 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3284 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003285 }
3286 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003287 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003288 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003289 }
mpagenkof1fc3862021-02-16 10:09:52 +00003290 } else {
3291 dh.lockVlanConfig.RUnlock()
3292 }
mpagenkodff5dda2020-08-28 11:52:01 +00003293}
3294
3295//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3296// 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 +00003297func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3298 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003299 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3300 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003301 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303302 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003303 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003304}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003305
mpagenkof1fc3862021-02-16 10:09:52 +00003306//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3307func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3308 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3309 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3310 // obviously then parallel processing on the cancel must be avoided
3311 // deadline context to ensure completion of background routines waited for
3312 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3313 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3314 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3315
3316 aPDevEntry.resetKvProcessingErrorIndication()
3317 var wg sync.WaitGroup
3318 wg.Add(1) // for the 1 go routine to finish
3319
3320 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3321 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3322
3323 return aPDevEntry.getKvProcessingErrorIndication()
3324}
3325
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003326//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3327//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003328func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3329 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003330
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003331 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003332 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003333 return nil
3334 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003335 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003336
dbainbri4d3a0dc2020-12-02 00:33:42 +00003337 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003338 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003339 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003340 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3341 }
3342 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3343
mpagenkof1fc3862021-02-16 10:09:52 +00003344 if aWriteToKvStore {
3345 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3346 }
3347 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003348}
3349
dbainbri4d3a0dc2020-12-02 00:33:42 +00003350func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003351 defer cancel() //ensure termination of context (may be pro forma)
3352 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003353 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003354 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003355}
3356
dbainbri4d3a0dc2020-12-02 00:33:42 +00003357func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003358
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003359 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003360 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003361 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003362 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3363 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003364 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003365 return err
3366 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003367 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003368 return nil
3369 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003370 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003371 return nil
3372}
3373
dbainbri4d3a0dc2020-12-02 00:33:42 +00003374func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3375 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003376 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003377 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003378 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3379 }
mpagenkof1fc3862021-02-16 10:09:52 +00003380 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003381}
3382
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003383// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003384// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003385func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3386 dh.lockDevice.RLock()
3387 defer dh.lockDevice.RUnlock()
3388 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3389 return uniPort.entityID, nil
3390 }
3391 return 0, errors.New("error-fetching-uni-port")
3392}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003393
3394// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003395func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3396 var errorsList []error
3397 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 -08003398
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003399 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3400 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3401 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3402
3403 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3404 // successfully.
3405 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3406 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3407 if len(errorsList) > 0 {
3408 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3409 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003410 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003411 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3412 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003413}
3414
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003415func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3416 var err error
3417 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003418 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003419
3420 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3421 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3422 errorsList = append(errorsList, err)
3423 }
3424 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003425 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003426
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003427 return errorsList
3428}
3429
3430func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3431 var err error
3432 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003433 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003434 // Check if group metric related config is updated
3435 for _, v := range pmConfigs.Groups {
3436 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3437 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3438 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3439
3440 if ok && m.frequency != v.GroupFreq {
3441 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3442 errorsList = append(errorsList, err)
3443 }
3444 }
3445 if ok && m.enabled != v.Enabled {
3446 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3447 errorsList = append(errorsList, err)
3448 }
3449 }
3450 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003451 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003452 return errorsList
3453}
3454
3455func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3456 var err error
3457 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003458 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003459 // Check if standalone metric related config is updated
3460 for _, v := range pmConfigs.Metrics {
3461 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003462 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003463 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3464
3465 if ok && m.frequency != v.SampleFreq {
3466 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3467 errorsList = append(errorsList, err)
3468 }
3469 }
3470 if ok && m.enabled != v.Enabled {
3471 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3472 errorsList = append(errorsList, err)
3473 }
3474 }
3475 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003476 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003477 return errorsList
3478}
3479
3480// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003481func (dh *deviceHandler) startCollector(ctx context.Context) {
3482 logger.Debugf(ctx, "startingCollector")
3483
3484 // Start routine to process OMCI GET Responses
3485 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303486 // Create Extended Frame PM ME
3487 go dh.pOnuMetricsMgr.createEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003488 // Initialize the next metric collection time.
3489 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3490 // reset like onu rebooted.
3491 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003492 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003493 for {
3494 select {
3495 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003496 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003497 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003498 // Stop the L2 PM FSM
3499 go func() {
3500 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3501 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3502 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3503 }
3504 } else {
3505 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3506 }
3507 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003508 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3509 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3510 }
3511 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3512 dh.pOnuMetricsMgr.stopTicks <- true
3513 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003514
Girish Gowdrae09a6202021-01-12 18:10:59 -08003515 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003516 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3517 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3518 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3519 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3520 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003521 // Update the next metric collection time.
3522 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003523 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003524 } else {
3525 if dh.pmConfigs.Grouped { // metrics are managed as a group
3526 // parse through the group and standalone metrics to see it is time to collect their metrics
3527 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003528
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003529 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3530 // 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 -08003531 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3532 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003533 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3534 }
3535 }
3536 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3537 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3538 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3539 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3540 }
3541 }
3542 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3543
3544 // parse through the group and update the next metric collection time
3545 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3546 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3547 // 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 -08003548 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3549 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003550 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3551 }
3552 }
3553 // parse through the standalone metrics and update the next metric collection time
3554 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3555 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3556 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3557 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3558 }
3559 }
3560 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3561 } /* else { // metrics are not managed as a group
3562 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3563 } */
3564 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003565 }
3566 }
3567}
kesavandfdf77632021-01-26 23:40:33 -05003568
3569func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3570
3571 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3572 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3573}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003574
Himani Chawla43f95ff2021-06-03 00:24:12 +05303575func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3576 if dh.pOnuMetricsMgr == nil {
3577 return &extension.SingleGetValueResponse{
3578 Response: &extension.GetValueResponse{
3579 Status: extension.GetValueResponse_ERROR,
3580 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3581 },
3582 }
3583 }
3584 resp := dh.pOnuMetricsMgr.collectEthernetFrameExtendedPMCounters(ctx)
3585 return resp
3586}
3587
mpagenkof1fc3862021-02-16 10:09:52 +00003588func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3589 if pFsm == nil {
3590 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003591 }
mpagenkof1fc3862021-02-16 10:09:52 +00003592 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003593}
3594
mpagenkof1fc3862021-02-16 10:09:52 +00003595func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
mpagenko9c225032021-10-15 14:26:49 +00003596 var pAdapterFsm *AdapterFsm
3597 //note/TODO!!: might be that access to all these specific FSM pointers need a semaphore protection as well, cmp lockUpgradeFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003598 switch omciFsm {
3599 case cUploadFsm:
3600 {
mpagenko9c225032021-10-15 14:26:49 +00003601 if dh.pOnuOmciDevice != nil {
3602 pAdapterFsm = dh.pOnuOmciDevice.pMibUploadFsm
3603 } else {
3604 return true //FSM not active - so there is no activity on omci
3605 }
mpagenkof1fc3862021-02-16 10:09:52 +00003606 }
3607 case cDownloadFsm:
3608 {
mpagenko9c225032021-10-15 14:26:49 +00003609 if dh.pOnuOmciDevice != nil {
3610 pAdapterFsm = dh.pOnuOmciDevice.pMibDownloadFsm
3611 } else {
3612 return true //FSM not active - so there is no activity on omci
3613 }
mpagenkof1fc3862021-02-16 10:09:52 +00003614 }
3615 case cUniLockFsm:
3616 {
mpagenko9c225032021-10-15 14:26:49 +00003617 if dh.pLockStateFsm != nil {
3618 pAdapterFsm = dh.pLockStateFsm.pAdaptFsm
3619 } else {
3620 return true //FSM not active - so there is no activity on omci
3621 }
mpagenkof1fc3862021-02-16 10:09:52 +00003622 }
3623 case cUniUnLockFsm:
3624 {
mpagenko9c225032021-10-15 14:26:49 +00003625 if dh.pUnlockStateFsm != nil {
3626 pAdapterFsm = dh.pUnlockStateFsm.pAdaptFsm
3627 } else {
3628 return true //FSM not active - so there is no activity on omci
3629 }
mpagenkof1fc3862021-02-16 10:09:52 +00003630 }
3631 case cL2PmFsm:
3632 {
mpagenko9c225032021-10-15 14:26:49 +00003633 if dh.pOnuMetricsMgr != nil {
3634 pAdapterFsm = dh.pOnuMetricsMgr.pAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003635 } else {
3636 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003637 }
3638 }
mpagenko80622a52021-02-09 16:53:23 +00003639 case cOnuUpgradeFsm:
3640 {
3641 dh.lockUpgradeFsm.RLock()
3642 defer dh.lockUpgradeFsm.RUnlock()
mpagenko9c225032021-10-15 14:26:49 +00003643 if dh.pOnuUpradeFsm != nil {
3644 pAdapterFsm = dh.pOnuUpradeFsm.pAdaptFsm
3645 } else {
3646 return true //FSM not active - so there is no activity on omci
3647 }
mpagenko80622a52021-02-09 16:53:23 +00003648 }
mpagenkof1fc3862021-02-16 10:09:52 +00003649 default:
3650 {
3651 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3652 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3653 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003654 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003655 }
mpagenko9c225032021-10-15 14:26:49 +00003656 if pAdapterFsm != nil && pAdapterFsm.pFsm != nil {
3657 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.pFsm, wantedState)
3658 }
3659 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003660}
3661
mpagenkof1fc3862021-02-16 10:09:52 +00003662func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3663 for _, v := range dh.pOnuTP.pAniConfigFsm {
3664 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003665 return false
3666 }
3667 }
3668 return true
3669}
3670
mpagenkof1fc3862021-02-16 10:09:52 +00003671func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3672 dh.lockVlanConfig.RLock()
3673 defer dh.lockVlanConfig.RUnlock()
3674 for _, v := range dh.UniVlanConfigFsmMap {
3675 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3676 return false
3677 }
3678 }
3679 return true //FSM not active - so there is no activity on omci
3680}
3681
3682func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3683 dh.lockVlanConfig.RLock()
3684 defer dh.lockVlanConfig.RUnlock()
3685 for _, v := range dh.UniVlanConfigFsmMap {
3686 if v.pAdaptFsm.pFsm != nil {
3687 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3688 return true //there is at least one VLAN FSM with some active configuration
3689 }
3690 }
3691 }
3692 return false //there is no VLAN FSM with some active configuration
3693}
3694
3695func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3696 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3697 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3698 return false
3699 }
3700 }
3701 // a further check is done to identify, if at least some data traffic related configuration exists
3702 // 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])
3703 return dh.checkUserServiceExists(ctx)
3704}
3705
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003706func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3707 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3708 if err := dh.resetFsms(ctx, false); err != nil {
3709 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3710 // TODO: fatal error reset ONU, delete deviceHandler!
3711 return
3712 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003713 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003714 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003715}
3716
3717func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3718 dh.mutexCollectorFlag.Lock()
3719 dh.collectorIsRunning = flagValue
3720 dh.mutexCollectorFlag.Unlock()
3721}
3722
3723func (dh *deviceHandler) getCollectorIsRunning() bool {
3724 dh.mutexCollectorFlag.RLock()
3725 flagValue := dh.collectorIsRunning
3726 dh.mutexCollectorFlag.RUnlock()
3727 return flagValue
3728}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303729
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303730func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3731 dh.mutextAlarmManagerFlag.Lock()
3732 dh.alarmManagerIsRunning = flagValue
3733 dh.mutextAlarmManagerFlag.Unlock()
3734}
3735
Himani Chawla1472c682021-03-17 17:11:14 +05303736func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303737 dh.mutextAlarmManagerFlag.RLock()
3738 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303739 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303740 dh.mutextAlarmManagerFlag.RUnlock()
3741 return flagValue
3742}
3743
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303744func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3745 logger.Debugf(ctx, "startingAlarmManager")
3746
3747 // Start routine to process OMCI GET Responses
3748 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303749 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303750 if stop := <-dh.stopAlarmManager; stop {
3751 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303752 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303753 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303754 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3755 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3756 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303757 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303758 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303759 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3760 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303761 }
3762}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003763
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003764func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003765 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003766
Maninder7961d722021-06-16 22:10:28 +05303767 connectStatus := voltha.ConnectStatus_UNREACHABLE
3768 operState := voltha.OperStatus_UNKNOWN
3769
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003770 if !dh.isReconciling() {
3771 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003772 logger.Debugw(ctx, "wait for channel signal or timeout",
3773 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003774 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003775 case success := <-dh.chReconcilingFinished:
Holger Hildebrandt6be98372022-01-06 14:49:08 +00003776 logger.Debugw(ctx, "reconciling finished signal received",
3777 log.Fields{"device-id": dh.deviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
3778 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
3779 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
3780 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
3781 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
3782 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
3783 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
3784 // However, a later refactoring of the functionality remains unaffected.
3785 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003786 if success {
Maninderb5187552021-03-23 22:23:42 +05303787 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3788 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3789 log.Fields{"device-id": dh.deviceID})
3790 } else {
mpagenkob59fbed2021-11-23 16:55:20 +00003791 onuDevEntry.mutexPersOnuConfig.RLock()
Maninderb5187552021-03-23 22:23:42 +05303792 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3793 connectStatus = voltha.ConnectStatus_REACHABLE
3794 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3795 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3796 operState = voltha.OperStatus_ACTIVE
3797 } else {
3798 operState = voltha.OperStatus_ACTIVATING
3799 }
3800 }
3801 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3802 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3803 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3804 operState = voltha.OperStatus_DISCOVERED
3805 }
mpagenkob59fbed2021-11-23 16:55:20 +00003806 onuDevEntry.mutexPersOnuConfig.RUnlock()
Maninderb5187552021-03-23 22:23:42 +05303807 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303808 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003809 logger.Debugw(ctx, "reconciling has been finished in time",
3810 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303811 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, operState); err != nil {
3812 logger.Errorw(ctx, "unable to update device state to core",
3813 log.Fields{"device-id": dh.deviceID, "Err": err})
3814 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003815 } else {
Maninderb5187552021-03-23 22:23:42 +05303816 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003817 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303818
3819 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3820 logger.Errorw(ctx, "No valid OnuDevice",
3821 log.Fields{"device-id": dh.deviceID})
mpagenkob59fbed2021-11-23 16:55:20 +00003822 } else {
3823 onuDevEntry.mutexPersOnuConfig.RLock()
3824 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3825 connectStatus = voltha.ConnectStatus_REACHABLE
3826 }
3827 onuDevEntry.mutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05303828 }
3829
3830 dh.deviceReconcileFailedUpdate(ctx, drReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003831 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003832 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003833 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3834 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt6be98372022-01-06 14:49:08 +00003835 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05303836
3837 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3838 logger.Errorw(ctx, "No valid OnuDevice",
3839 log.Fields{"device-id": dh.deviceID})
mpagenkob59fbed2021-11-23 16:55:20 +00003840 } else {
3841 onuDevEntry.mutexPersOnuConfig.RLock()
3842 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3843 connectStatus = voltha.ConnectStatus_REACHABLE
3844 }
3845 onuDevEntry.mutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05303846 }
Maninder7961d722021-06-16 22:10:28 +05303847 dh.deviceReconcileFailedUpdate(ctx, drReconcileMaxTimeout, connectStatus)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003848 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003849 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003850 dh.mutexReconcilingFlag.Unlock()
3851 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003852 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003853 dh.mutexReconcilingFlag.Lock()
3854 if skipOnuConfig {
3855 dh.reconciling = cSkipOnuConfigReconciling
3856 } else {
3857 dh.reconciling = cOnuConfigReconciling
3858 }
3859 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003860}
3861
Girish Gowdra50e56422021-06-01 16:46:04 -07003862func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool) {
3863 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID, "success": success})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003864 if dh.isReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07003865 dh.chReconcilingFinished <- success
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003866 } else {
3867 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3868 }
3869}
3870
3871func (dh *deviceHandler) isReconciling() bool {
3872 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003873 defer dh.mutexReconcilingFlag.RUnlock()
3874 return dh.reconciling != cNoReconciling
3875}
3876
3877func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3878 dh.mutexReconcilingFlag.RLock()
3879 defer dh.mutexReconcilingFlag.RUnlock()
3880 return dh.reconciling == cSkipOnuConfigReconciling
3881}
3882
3883func (dh *deviceHandler) setDeviceReason(value uint8) {
3884 dh.mutexDeviceReason.Lock()
3885 dh.deviceReason = value
3886 dh.mutexDeviceReason.Unlock()
3887}
3888
3889func (dh *deviceHandler) getDeviceReason() uint8 {
3890 dh.mutexDeviceReason.RLock()
3891 value := dh.deviceReason
3892 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003893 return value
3894}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003895
3896func (dh *deviceHandler) getDeviceReasonString() string {
3897 return deviceReasonMap[dh.getDeviceReason()]
3898}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003899
3900func (dh *deviceHandler) setReconcilingFlows(value bool) {
3901 dh.mutexReconcilingFlowsFlag.Lock()
3902 dh.reconcilingFlows = value
3903 dh.mutexReconcilingFlowsFlag.Unlock()
3904}
3905
3906func (dh *deviceHandler) isReconcilingFlows() bool {
3907 dh.mutexReconcilingFlowsFlag.RLock()
3908 value := dh.reconcilingFlows
3909 dh.mutexReconcilingFlowsFlag.RUnlock()
3910 return value
3911}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003912
3913func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3914 dh.mutexReadyForOmciConfig.Lock()
3915 dh.readyForOmciConfig = flagValue
3916 dh.mutexReadyForOmciConfig.Unlock()
3917}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003918func (dh *deviceHandler) isReadyForOmciConfig() bool {
3919 dh.mutexReadyForOmciConfig.RLock()
3920 flagValue := dh.readyForOmciConfig
3921 dh.mutexReadyForOmciConfig.RUnlock()
3922 return flagValue
3923}
Maninder7961d722021-06-16 22:10:28 +05303924
3925func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
3926 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
3927 logger.Errorw(ctx, "unable to update device reason to core",
3928 log.Fields{"device-id": dh.deviceID, "Err": err})
3929 }
3930
3931 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
3932 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, voltha.OperStatus_RECONCILING_FAILED); err != nil {
3933 logger.Errorw(ctx, "unable to update device state to core",
3934 log.Fields{"device-id": dh.deviceID, "Err": err})
3935 }
3936}
Holger Hildebrandt72eaab72021-11-05 08:54:59 +00003937
3938// GetUniVlanConfigFsm - returns pointer to UniVlanConfigFsm
3939func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) *UniVlanConfigFsm {
3940 dh.lockVlanConfig.RLock()
3941 value := dh.UniVlanConfigFsmMap[uniID]
3942 dh.lockVlanConfig.RUnlock()
3943 return value
3944}