blob: 7674cc8258f18923e62bf4a7fe33652b76518f57 [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
Holger Hildebrandt779e8d62022-02-08 15:35:01 +000049const (
50 //constants for reconcile flow check channel
51 cWaitReconcileFlowAbortOnSuccess = 0xFFFD
52 cWaitReconcileFlowAbortOnError = 0xFFFE
53 cWaitReconcileFlowNoActivity = 0xFFFF
54)
55
mpagenko9c225032021-10-15 14:26:49 +000056// Constants for timeouts
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000057const (
mpagenko9c225032021-10-15 14:26:49 +000058 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000059)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000060
mpagenko1cc3cb42020-07-27 15:24:38 +000061const (
Holger Hildebrandt3d77f9c2022-01-12 10:45:13 +000062 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
63 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
64 // as long as such is not available by the libraries - use this workaround
65 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
66)
67
68const (
mpagenko1cc3cb42020-07-27 15:24:38 +000069 // events of Device FSM
70 devEvDeviceInit = "devEvDeviceInit"
71 devEvGrpcConnected = "devEvGrpcConnected"
72 devEvGrpcDisconnected = "devEvGrpcDisconnected"
73 devEvDeviceUpInd = "devEvDeviceUpInd"
74 devEvDeviceDownInd = "devEvDeviceDownInd"
75)
76const (
77 // states of Device FSM
78 devStNull = "devStNull"
79 devStDown = "devStDown"
80 devStInit = "devStInit"
81 devStConnected = "devStConnected"
82 devStUp = "devStUp"
83)
84
Holger Hildebrandt24d51952020-05-04 14:03:42 +000085//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
86const (
Himani Chawla4d908332020-08-31 12:30:20 +053087 pon = voltha.EventSubCategory_PON
88 //olt = voltha.EventSubCategory_OLT
89 //ont = voltha.EventSubCategory_ONT
90 //onu = voltha.EventSubCategory_ONU
91 //nni = voltha.EventSubCategory_NNI
92 //service = voltha.EventCategory_SERVICE
93 //security = voltha.EventCategory_SECURITY
94 equipment = voltha.EventCategory_EQUIPMENT
95 //processing = voltha.EventCategory_PROCESSING
96 //environment = voltha.EventCategory_ENVIRONMENT
97 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000098)
99
100const (
101 cEventObjectType = "ONU"
102)
103const (
104 cOnuActivatedEvent = "ONU_ACTIVATED"
105)
106
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000107type usedOmciConfigFsms int
108
109const (
110 cUploadFsm usedOmciConfigFsms = iota
111 cDownloadFsm
112 cUniLockFsm
113 cUniUnLockFsm
114 cAniConfigFsm
115 cUniVlanConfigFsm
Girish Gowdrae0140f02021-02-02 16:55:09 -0800116 cL2PmFsm
mpagenko80622a52021-02-09 16:53:23 +0000117 cOnuUpgradeFsm
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000118)
119
mpagenkof1fc3862021-02-16 10:09:52 +0000120type omciIdleCheckStruct struct {
121 omciIdleCheckFunc func(*deviceHandler, context.Context, usedOmciConfigFsms, string) bool
122 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000123}
124
mpagenkof1fc3862021-02-16 10:09:52 +0000125var fsmOmciIdleStateFuncMap = map[usedOmciConfigFsms]omciIdleCheckStruct{
126 cUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibUlFsmIdleState},
127 cDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibDlFsmIdleState},
128 cUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
129 cUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
130 cAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, cAniFsmIdleState},
131 cUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, cVlanFsmIdleState},
132 cL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cL2PmFsmIdleState},
mpagenko80622a52021-02-09 16:53:23 +0000133 cOnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cOnuUpgradeFsmIdleState},
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000134}
135
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000136const (
137 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000138 drUnset = 0
139 drActivatingOnu = 1
140 drStartingOpenomci = 2
141 drDiscoveryMibsyncComplete = 3
142 drInitialMibDownloaded = 4
143 drTechProfileConfigDownloadSuccess = 5
144 drOmciFlowsPushed = 6
145 drOmciAdminLock = 7
146 drOnuReenabled = 8
147 drStoppingOpenomci = 9
148 drRebooting = 10
149 drOmciFlowsDeleted = 11
150 drTechProfileConfigDeleteSuccess = 12
Maninder7961d722021-06-16 22:10:28 +0530151 drReconcileFailed = 13
152 drReconcileMaxTimeout = 14
153 drReconcileCanceled = 15
Girish Gowdra50e56422021-06-01 16:46:04 -0700154 drTechProfileConfigDownloadFailed = 16
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000155)
156
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000157var deviceReasonMap = map[uint8]string{
158 drUnset: "unset",
159 drActivatingOnu: "activating-onu",
160 drStartingOpenomci: "starting-openomci",
161 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
162 drInitialMibDownloaded: "initial-mib-downloaded",
163 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
Girish Gowdra50e56422021-06-01 16:46:04 -0700164 drTechProfileConfigDownloadFailed: "tech-profile-config-download-failed",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000165 drOmciFlowsPushed: "omci-flows-pushed",
166 drOmciAdminLock: "omci-admin-lock",
167 drOnuReenabled: "onu-reenabled",
168 drStoppingOpenomci: "stopping-openomci",
169 drRebooting: "rebooting",
170 drOmciFlowsDeleted: "omci-flows-deleted",
171 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
Maninder7961d722021-06-16 22:10:28 +0530172 drReconcileFailed: "reconcile-failed",
173 drReconcileMaxTimeout: "reconcile-max-timeout",
174 drReconcileCanceled: "reconciling-canceled",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000175}
176
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000177const (
178 cNoReconciling = iota
179 cOnuConfigReconciling
180 cSkipOnuConfigReconciling
181)
182
Holger Hildebrandt779e8d62022-02-08 15:35:01 +0000183//WaitGroupWithTimeOut definitions to have waitGroup functionality with timeout
184type WaitGroupWithTimeOut struct {
185 sync.WaitGroup
186}
187
Himani Chawla6d2ae152020-09-02 13:11:20 +0530188//deviceHandler will interact with the ONU ? device.
189type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000190 deviceID string
191 DeviceType string
192 adminState string
193 device *voltha.Device
194 logicalDeviceID string
195 ProxyAddressID string
196 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530197 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000198 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000199
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000200 coreProxy adapterif.CoreProxy
201 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530202 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000203
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800204 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800205
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000206 pOpenOnuAc *OpenONUAC
207 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530208 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000209 deviceEntrySet chan bool //channel for DeviceEntry set event
210 pOnuOmciDevice *OnuDeviceEntry
211 pOnuTP *onuUniTechProf
212 pOnuMetricsMgr *onuMetricsManager
213 pAlarmMgr *onuAlarmManager
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700214 pSelfTestHdlr *selfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000215 exitChannel chan int
216 lockDevice sync.RWMutex
217 pOnuIndication *oop.OnuIndication
218 deviceReason uint8
219 mutexDeviceReason sync.RWMutex
220 pLockStateFsm *lockStateFsm
221 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000222
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000223 //flowMgr *OpenOltFlowMgr
224 //eventMgr *OpenOltEventMgr
225 //resourceMgr *rsrcMgr.OpenOltResourceMgr
226
227 //discOnus sync.Map
228 //onus sync.Map
229 //portStats *OpenOltStatisticsMgr
Holger Hildebrandt779e8d62022-02-08 15:35:01 +0000230 collectorIsRunning bool
231 mutexCollectorFlag sync.RWMutex
232 stopCollector chan bool
233 alarmManagerIsRunning bool
234 mutextAlarmManagerFlag sync.RWMutex
235 stopAlarmManager chan bool
236 stopHeartbeatCheck chan bool
237 uniEntityMap map[uint32]*onuUniPort
238 mutexKvStoreContext sync.Mutex
239 lockVlanConfig sync.RWMutex
240 lockVlanAdd sync.RWMutex
241 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
242 lockUpgradeFsm sync.RWMutex
243 pOnuUpradeFsm *OnuUpgradeFsm
244 upgradeCanceled bool
245 reconciling uint8
246 mutexReconcilingFlag sync.RWMutex
247 reconcilingFirstPass bool
248 mutexReconcilingFirstPassFlag sync.RWMutex
249 reconcilingReasonUpdate bool
250 mutexReconcilingReasonUpdate sync.RWMutex
251 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
252 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
253 reconcileExpiryComplete time.Duration
254 reconcileExpiryVlanConfig time.Duration
255 mutexReadyForOmciConfig sync.RWMutex
256 readyForOmciConfig bool
257 deletionInProgress bool
258 mutexDeletionInProgressFlag sync.RWMutex
259 pLastUpgradeImageState *voltha.ImageState
260 upgradeFsmChan chan struct{}
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000261}
262
Himani Chawla6d2ae152020-09-02 13:11:20 +0530263//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530264func 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 +0530265 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000266 dh.coreProxy = cp
267 dh.AdapterProxy = ap
268 dh.EventProxy = ep
269 cloned := (proto.Clone(device)).(*voltha.Device)
270 dh.deviceID = cloned.Id
271 dh.DeviceType = cloned.Type
272 dh.adminState = "up"
273 dh.device = cloned
274 dh.pOpenOnuAc = adapter
275 dh.exitChannel = make(chan int, 1)
276 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000277 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000278 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000279 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530280 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530281 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000282 dh.stopHeartbeatCheck = make(chan bool, 2)
283 //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 +0000284 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530285 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000286 dh.lockVlanConfig = sync.RWMutex{}
mpagenko2f487262021-08-23 15:59:06 +0000287 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000288 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000289 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000290 dh.reconciling = cNoReconciling
Holger Hildebrandt779e8d62022-02-08 15:35:01 +0000291 dh.reconcilingReasonUpdate = false
292 dh.reconcilingFirstPass = true
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000293 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandt779e8d62022-02-08 15:35:01 +0000294 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
295 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
296 if rECSeconds < 2 {
297 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
298 rECSeconds = 2
299 }
300 rEVCSeconds := rECSeconds / 2
301 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
302
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000303 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000304 dh.deletionInProgress = false
mpagenko9c225032021-10-15 14:26:49 +0000305 dh.pLastUpgradeImageState = &voltha.ImageState{
306 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
307 Reason: voltha.ImageState_UNKNOWN_ERROR,
308 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
309 }
310 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000311
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800312 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
313 dh.pmConfigs = cloned.PmConfigs
314 } /* else {
315 // will be populated when onu_metrics_mananger is initialized.
316 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800317
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000318 // Device related state machine
319 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000320 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000321 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000322 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
323 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
324 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
325 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
326 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000327 },
328 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000329 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
330 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
331 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
332 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
333 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
334 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
335 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
336 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000337 },
338 )
mpagenkoaf801632020-07-03 10:00:42 +0000339
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000340 return &dh
341}
342
Himani Chawla6d2ae152020-09-02 13:11:20 +0530343// start save the device to the data model
344func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000345 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000346 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000347 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000348}
349
Himani Chawla4d908332020-08-31 12:30:20 +0530350/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000351// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530352func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000353 logger.Debug("stopping-device-handler")
354 dh.exitChannel <- 1
355}
Himani Chawla4d908332020-08-31 12:30:20 +0530356*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000357
358// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530359// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000360
Girish Gowdrae0140f02021-02-02 16:55:09 -0800361//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530362func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000363 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000364
dbainbri4d3a0dc2020-12-02 00:33:42 +0000365 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000366 if dh.pDeviceStateFsm.Is(devStNull) {
367 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000368 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000369 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000370 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800371 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
372 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800373 // Now, set the initial PM configuration for that device
374 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
375 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
376 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800377 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000378 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000379 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000380 }
381
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000382}
383
mpagenko057889c2021-01-21 16:51:58 +0000384func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530385 msgBody := msg.GetBody()
386 omciMsg := &ic.InterAdapterOmciMessage{}
387 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000388 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530389 "device-id": dh.deviceID, "error": err})
390 return err
391 }
392
mpagenko80622a52021-02-09 16:53:23 +0000393 /* 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 +0530394 //assuming omci message content is hex coded!
395 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000396 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530397 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000398 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000399 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530400 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000401 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000402 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000403 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000404 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 +0530405 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000406 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000407 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530408}
409
Himani Chawla6d2ae152020-09-02 13:11:20 +0530410func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000411 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530412 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000413
dbainbri4d3a0dc2020-12-02 00:33:42 +0000414 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000415
dbainbri4d3a0dc2020-12-02 00:33:42 +0000416 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000417 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000418 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000419 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
420 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530421 if dh.pOnuTP == nil {
422 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000423 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530424 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000425 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530426 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000427 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000428 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000429 "device-state": dh.getDeviceReasonString()})
430 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530431 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000432 //previous state test here was just this one, now extended for more states to reject the SetRequest:
433 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
434 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530435
436 msgBody := msg.GetBody()
437 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
438 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000439 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530440 "device-id": dh.deviceID, "error": err})
441 return err
442 }
443
444 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000445 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
446 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530447 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000448 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000449
450 if techProfMsg.UniId > 255 {
451 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
452 techProfMsg.UniId, dh.deviceID))
453 }
454 uniID := uint8(techProfMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700455 tpID, err := GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800456 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700457 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800458 return err
459 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700460 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000461
Girish Gowdra50e56422021-06-01 16:46:04 -0700462 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530463
Girish Gowdra50e56422021-06-01 16:46:04 -0700464 switch tpInst := techProfMsg.TechTpInstance.(type) {
465 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance:
466 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
467 // if there has been some change for some uni TechProfilePath
468 //in order to allow concurrent calls to other dh instances we do not wait for execution here
469 //but doing so we can not indicate problems to the caller (who does what with that then?)
470 //by now we just assume straightforward successful execution
471 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
472 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530473
Girish Gowdra50e56422021-06-01 16:46:04 -0700474 // deadline context to ensure completion of background routines waited for
475 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
476 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
477 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000478
Girish Gowdra50e56422021-06-01 16:46:04 -0700479 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
480
481 var wg sync.WaitGroup
482 wg.Add(1) // for the 1 go routine to finish
483 // attention: deadline completion check and wg.Done is to be done in both routines
484 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
485 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
486 if tpErr := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
487 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.deviceID, "err": tpErr, "tp-path": techProfMsg.TpInstancePath})
488 return tpErr
489 }
490 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
491 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
492 pDevEntry.resetKvProcessingErrorIndication()
493 wg.Add(1) // for the 1 go routine to finish
494 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
495 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
496 if kvErr := pDevEntry.getKvProcessingErrorIndication(); kvErr != nil {
497 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.deviceID, "err": kvErr, "tp-path": techProfMsg.TpInstancePath})
498 return kvErr
499 }
500 return nil
501 default:
502 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"tp-path": techProfMsg.TpInstancePath})
503 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700504 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530505 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000506 // no change, nothing really to do - return success
Girish Gowdra50e56422021-06-01 16:46:04 -0700507 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 +0530508 return nil
509}
510
Himani Chawla6d2ae152020-09-02 13:11:20 +0530511func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000512 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530513 msg *ic.InterAdapterMessage) error {
514
515 if dh.pOnuTP == nil {
516 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000517 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530518 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000519 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530520 }
521
522 msgBody := msg.GetBody()
523 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
524 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000525 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530526 "device-id": dh.deviceID, "error": err})
527 return err
528 }
529
530 //compare TECH_PROFILE_DOWNLOAD_REQUEST
531 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000532 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530533
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000534 if delGemPortMsg.UniId > 255 {
535 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
536 delGemPortMsg.UniId, dh.deviceID))
537 }
538 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700539 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800540 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700541 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 -0800542 return err
543 }
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700544 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 +0000545 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000546
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700547 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
548 cResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000549
Himani Chawla26e555c2020-08-31 12:30:20 +0530550}
551
Himani Chawla6d2ae152020-09-02 13:11:20 +0530552func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000553 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530554 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000555
dbainbri4d3a0dc2020-12-02 00:33:42 +0000556 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000557 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000558 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000559 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
560 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530561 if dh.pOnuTP == nil {
562 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000563 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530564 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000565 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530566 }
567
568 msgBody := msg.GetBody()
569 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
570 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000571 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530572 "device-id": dh.deviceID, "error": err})
573 return err
574 }
575
576 //compare TECH_PROFILE_DOWNLOAD_REQUEST
577 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000578 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000579
580 if delTcontMsg.UniId > 255 {
581 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
582 delTcontMsg.UniId, dh.deviceID))
583 }
584 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700585 tpPath := delTcontMsg.TpInstancePath
Girish Gowdra041dcb32020-11-16 16:54:30 -0800586 tpID, err := GetTpIDFromTpPath(tpPath)
587 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000588 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800589 return err
590 }
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700591 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 +0000592
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700593 pDevEntry.freeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530594
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700595 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
596 cResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000597
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700598}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000599
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700600func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
601 uniID uint8, tpID uint8, pathString string, resource resourceEntry, entryID uint32) error {
602 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
603 if pDevEntry == nil {
604 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
605 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530606 }
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700607 var resourceName string
608 if cResourceGemPort == resource {
609 resourceName = "Gem"
610 } else {
611 resourceName = "Tcont"
612 }
613
614 // deadline context to ensure completion of background routines waited for
615 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
616 dctx, cancel := context.WithDeadline(context.Background(), deadline)
617
618 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
619
620 var wg sync.WaitGroup
621 wg.Add(1) // for the 1 go routine to finish
622 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
623 resource, entryID, &wg)
624 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
625 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); err != nil {
626 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
627 return err
628 }
629
630 if dh.pOnuTP.isTechProfileConfigCleared(ctx, uniID, tpID) {
631 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID})
632 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
633 pDevEntry.resetKvProcessingErrorIndication()
634 var wg2 sync.WaitGroup
635 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
636 wg2.Add(1)
637 // Removal of the gem id mapping represents the removal of the tech profile
638 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID})
639 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
640 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
641 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
642 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
643 return err
644 }
645 }
646 }
647 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.deviceID,
648 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530649 return nil
650}
651
Himani Chawla6d2ae152020-09-02 13:11:20 +0530652//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000653// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
654// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000655func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000656 msgID := msg.Header.Id
657 msgType := msg.Header.Type
658 fromTopic := msg.Header.FromTopic
659 toTopic := msg.Header.ToTopic
660 toDeviceID := msg.Header.ToDeviceId
661 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000662 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000663 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
664
665 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000666 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000667 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
668 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000669 {
mpagenko057889c2021-01-21 16:51:58 +0000670 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000671 }
mpagenkoaf801632020-07-03 10:00:42 +0000672 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
673 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000674 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000675 }
676 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
677 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000678 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000679
mpagenkoaf801632020-07-03 10:00:42 +0000680 }
681 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
682 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000683 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000684 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000685 default:
686 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000687 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000688 "msgType": msg.Header.Type, "device-id": dh.deviceID})
689 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000690 }
691 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000692}
693
mpagenkodff5dda2020-08-28 11:52:01 +0000694//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000695func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
696 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000697 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
ozgecanetsia82b91a62021-05-21 18:54:49 +0300698 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID, "metadata": apFlowMetaData})
mpagenko01e726e2020-10-23 09:45:29 +0000699 var retError error = nil
700 //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 +0000701 if apOfFlowChanges.ToRemove != nil {
702 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000703 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000704 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000705 "device-id": dh.deviceID})
706 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000707 continue
708 }
709 flowInPort := flow.GetInPort(flowItem)
710 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000711 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 +0000712 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
713 continue
714 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000715 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000716 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000717 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000718 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000719 continue
720 } else {
721 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530722 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000723 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
724 loUniPort = uniPort
725 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000726 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000727 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
728 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
729 flowInPort, dh.deviceID)
730 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000731 }
732 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000733 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000734 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000735 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000736 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000737 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000738 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000739 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000740 log.Fields{"device-id": dh.deviceID, "error": err})
741 retError = err
742 continue
743 //return err
744 } else { // if last setting succeeds, overwrite possibly previously set error
745 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000746 }
747 }
748 }
749 }
mpagenko01e726e2020-10-23 09:45:29 +0000750 if apOfFlowChanges.ToAdd != nil {
751 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
752 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000753 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000754 "device-id": dh.deviceID})
755 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
756 continue
757 }
758 flowInPort := flow.GetInPort(flowItem)
759 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000760 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 +0000761 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
762 continue
763 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
764 } else if flowInPort == dh.ponPortNumber {
765 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000766 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000767 "device-id": dh.deviceID, "inPort": flowInPort})
768 continue
769 } else {
770 // this is the relevant upstream flow
771 var loUniPort *onuUniPort
772 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
773 loUniPort = uniPort
774 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000775 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000776 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
777 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
778 flowInPort, dh.deviceID)
779 continue
780 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
781 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000782 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
783 // if not, we just throw some error here to have an indication about that, if we really need to support that
784 // then we would need to create some means to activate the internal stored flows
785 // after the device gets active automatically (and still with its dependency to the TechProfile)
786 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
787 // also abort for the other still possible flows here
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000788 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000789 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000790 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000791 return fmt.Errorf("improper device state on device %s", dh.deviceID)
792 }
793
mpagenko01e726e2020-10-23 09:45:29 +0000794 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000795 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000796 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
797 "uniPortName": loUniPort.name})
ozgecanetsia82b91a62021-05-21 18:54:49 +0300798 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort, apFlowMetaData)
mpagenko01e726e2020-10-23 09:45:29 +0000799 //try next flow after processing error
800 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000801 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000802 log.Fields{"device-id": dh.deviceID, "error": err})
803 retError = err
804 continue
805 //return err
806 } else { // if last setting succeeds, overwrite possibly previously set error
807 retError = nil
808 }
809 }
810 }
811 }
812 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000813}
814
Himani Chawla6d2ae152020-09-02 13:11:20 +0530815//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000816//following are the expected device states after this activity:
817//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
818// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000819func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
820 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000821
mpagenko900ee4b2020-10-12 11:56:34 +0000822 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000823 //note that disableDevice sequences in some 'ONU active' state may yield also
824 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000825 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000826 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000827 //disable-device shall be just a UNi/ONU-G related admin state setting
828 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000829
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000830 if dh.isReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000831 // disable UNI ports/ONU
832 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
833 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000834 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000835 } else { //LockStateFSM already init
836 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000837 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000838 }
839 } else {
Holger Hildebrandt3d77f9c2022-01-12 10:45:13 +0000840 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000841 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
Holger Hildebrandt3d77f9c2022-01-12 10:45:13 +0000842 // disable device should have no impact on ConnStatus
843 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
844 connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
845 voltha.OperStatus_UNKNOWN); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000846 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000847 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000848 }
mpagenko01e726e2020-10-23 09:45:29 +0000849 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000850
851 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000852 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000853 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300854 }
855}
856
Himani Chawla6d2ae152020-09-02 13:11:20 +0530857//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000858func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
859 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000860
mpagenkoaa3afe92021-05-21 16:20:58 +0000861 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000862 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
863 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
864 // for real ONU's that should have nearly no influence
865 // Note that for real ONU's there is anyway a problematic situation with following sequence:
866 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
867 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
868 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000869 dh.setReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000870
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000871 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000872 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000873 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000874 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000875 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000876 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000877 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000878 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300879}
880
dbainbri4d3a0dc2020-12-02 00:33:42 +0000881func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
882 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000883
dbainbri4d3a0dc2020-12-02 00:33:42 +0000884 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000885 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000886 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000887 return
888 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000889 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000890 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000891 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000892 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000893 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000894 }
Holger Hildebrandt779e8d62022-02-08 15:35:01 +0000895 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000896 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000897 }
Himani Chawla4d908332020-08-31 12:30:20 +0530898 var onuIndication oop.OnuIndication
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000899 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000900 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
901 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
902 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
903 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000904 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000905 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000906}
907
Holger Hildebrandt779e8d62022-02-08 15:35:01 +0000908func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) bool {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000909 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000910
Holger Hildebrandt779e8d62022-02-08 15:35:01 +0000911 continueWithFlowConfig := false
912
dbainbri4d3a0dc2020-12-02 00:33:42 +0000913 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000914 if pDevEntry == nil {
Holger Hildebrandt779e8d62022-02-08 15:35:01 +0000915 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
916 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
917 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000918 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000919 dh.pOnuTP.lockTpProcMutex()
920 defer dh.pOnuTP.unlockTpProcMutex()
921
mpagenko5dc85a02021-08-02 12:35:01 +0000922 pDevEntry.mutexPersOnuConfig.RLock()
923 persMutexLock := true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000924 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko5dc85a02021-08-02 12:35:01 +0000925 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000926 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000927 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt779e8d62022-02-08 15:35:01 +0000928 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
929 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000930 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000931 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700932 techProfsFound := false
933 techProfInstLoadFailed := false
934outerLoop:
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000935 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000936 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
937 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000938 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000939 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000940 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000941 }
mpagenko5dc85a02021-08-02 12:35:01 +0000942 //release mutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
943 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
944 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
945 pDevEntry.mutexPersOnuConfig.RUnlock()
946 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700947 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800948 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700949 // Request the TpInstance again from the openolt adapter in case of reconcile
950 iaTechTpInst, err := dh.AdapterProxy.TechProfileInstanceRequest(ctx, uniData.PersTpPathMap[tpID],
951 dh.device.ParentPortNo, dh.device.ProxyAddress.OnuId, uint32(uniData.PersUniID),
952 dh.pOpenOnuAc.config.Topic, dh.ProxyAddressType,
953 dh.parentID, dh.ProxyAddressID)
954 if err != nil || iaTechTpInst == nil {
955 logger.Errorw(ctx, "error fetching tp instance",
956 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID, "err": err})
957 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
958 break outerLoop
959 }
Holger Hildebrandt779e8d62022-02-08 15:35:01 +0000960 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700961 var tpInst tech_profile.TechProfileInstance
962 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
963 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
964 tpInst = *techTpInst.TpInstance
Holger Hildebrandt779e8d62022-02-08 15:35:01 +0000965 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
mpagenko5dc85a02021-08-02 12:35:01 +0000966 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700967 default: // do not support epon or other tech
Holger Hildebrandt779e8d62022-02-08 15:35:01 +0000968 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
mpagenko5dc85a02021-08-02 12:35:01 +0000969 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700970 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
971 break outerLoop
972 }
973
Girish Gowdra041dcb32020-11-16 16:54:30 -0800974 // deadline context to ensure completion of background routines waited for
975 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
976 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000977 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000978
Girish Gowdra041dcb32020-11-16 16:54:30 -0800979 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
980 var wg sync.WaitGroup
981 wg.Add(1) // for the 1 go routine to finish
Girish Gowdra50e56422021-06-01 16:46:04 -0700982 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000983 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800984 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000985 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700986 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
987 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800988 }
mpagenko5dc85a02021-08-02 12:35:01 +0000989 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000990 if len(uniData.PersFlowParams) != 0 {
991 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000992 }
mpagenko5dc85a02021-08-02 12:35:01 +0000993 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
994 persMutexLock = true
995 } // for all UNI entries from sOnuPersistentData
996 if persMutexLock { // if loop was left with mutexPersOnuConfig still set
997 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000998 }
mpagenko5dc85a02021-08-02 12:35:01 +0000999
1000 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
1001 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00001002
1003 return continueWithFlowConfig
mpagenko5dc85a02021-08-02 12:35:01 +00001004}
1005
1006func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
1007 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
1008 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001009 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
1010 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00001011 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001012 return
1013 }
mpagenko5dc85a02021-08-02 12:35:01 +00001014 if abTechProfInstLoadFailed {
Girish Gowdra50e56422021-06-01 16:46:04 -07001015 dh.setDeviceReason(drTechProfileConfigDownloadFailed)
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00001016 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -07001017 return
1018 } else if dh.isSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001019 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
1020 }
mpagenko5dc85a02021-08-02 12:35:01 +00001021 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001022 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
1023 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00001024 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001025 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001026}
1027
dbainbri4d3a0dc2020-12-02 00:33:42 +00001028func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
1029 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001030
dbainbri4d3a0dc2020-12-02 00:33:42 +00001031 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001032 if pDevEntry == nil {
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00001033 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1034 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001035 return
1036 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001037
mpagenko5dc85a02021-08-02 12:35:01 +00001038 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001039 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko5dc85a02021-08-02 12:35:01 +00001040 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001041 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001042 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00001043 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001044 return
1045 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001046 flowsFound := false
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00001047 var uniVlanConfigEntries []uint8
1048 var loWaitGroupWTO WaitGroupWithTimeOut
1049
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001050 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001051 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1052 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001053 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001054 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001055 continue
1056 }
1057 if len(uniData.PersTpPathMap) == 0 {
1058 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
1059 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001060 // It doesn't make sense to configure any flows if no TPs are available
1061 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001062 }
mpagenko5dc85a02021-08-02 12:35:01 +00001063 //release mutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1064 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
1065 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1066 pDevEntry.mutexPersOnuConfig.RUnlock()
1067
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001068 var uniPort *onuUniPort
1069 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +00001070 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001071 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001072 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
1073 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00001074 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
1075
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001076 return
1077 }
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00001078 //needed to split up function due to sca complexity
1079 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1080
mpagenko5dc85a02021-08-02 12:35:01 +00001081 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00001082 "device-id": dh.deviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001083 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
1084 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001085 // this can't be used as global finished reconciling flag because
1086 // assumes is getting called before the state machines for the last flow is completed,
1087 // while this is not guaranteed.
mpagenko5dc85a02021-08-02 12:35:01 +00001088 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
1089 } // for all UNI entries from sOnuPersistentData
1090 pDevEntry.mutexPersOnuConfig.RUnlock()
1091
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001092 if !flowsFound {
1093 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
1094 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00001095 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
1096 return
1097 }
1098 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1099 "device-id": dh.deviceID, "expiry": dh.reconcileExpiryVlanConfig})
1100 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1101 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1102 log.Fields{"device-id": dh.deviceID})
1103 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1104 if pDevEntry != nil {
1105 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
1106 }
1107 } else {
1108 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1109 log.Fields{"device-id": dh.deviceID})
1110 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1111 if pDevEntry != nil {
1112 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001113 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001114 return
1115 }
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00001116 dh.setDeviceReason(drOmciFlowsPushed)
1117}
1118
1119func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *onuUniPort,
1120 aPersFlowParam []uniVlanFlowParams, aUniVlanConfigEntries []uint8,
1121 apWaitGroup *WaitGroupWithTimeOut, apFlowsFound *bool) {
1122 flowsProcessed := 0
1123 lastFlowToReconcile := false
1124 loUniID := apUniPort.uniID
1125 for _, flowData := range aPersFlowParam {
1126 if !(*apFlowsFound) {
1127 *apFlowsFound = true
1128 syncChannel := make(chan struct{})
1129 // start go routine with select() on reconciling vlan config channel before
1130 // starting vlan config reconciling process to prevent loss of any signal
1131 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1132 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1133 //block until the wait routine is really blocked on channel input
1134 // in order to prevent to early ready signal from VlanConfig processing
1135 <-syncChannel
1136 }
1137 if flowsProcessed == len(aPersFlowParam)-1 {
1138 var uniAdded bool
1139 lastFlowToReconcile = true
1140 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1141 apWaitGroup.Add(1) //increment the waiting group
1142 }
1143 }
1144 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1145 "device-id": dh.deviceID, "uni-id": loUniID,
1146 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1147 dh.lockVlanConfig.Lock()
1148 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1149 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1150 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
1151 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1152 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter); err != nil {
1153 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
1154 }
1155 } else {
1156 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
1157 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1158 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter); err != nil {
1159 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
1160 }
1161 }
1162 dh.lockVlanConfig.Unlock()
1163 flowsProcessed++
1164 } //for all flows of this UNI
1165}
1166
1167//waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1168// and decrements the according handler wait group waiting for these indications
1169func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1170 waitGroup *WaitGroupWithTimeOut) {
1171 var reconciledUniVlanConfigEntries []uint8
1172 var appended bool
1173 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1174 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1175 "device-id": dh.deviceID, "expiry": expiry})
1176 // indicate blocking on channel now to the caller
1177 aSyncChannel <- struct{}{}
1178 cycle := 1
1179 for {
1180 logger.Debugw(ctx, "waiting on reconcile vlanConfig ready indications",
1181 log.Fields{"device-id": dh.deviceID, "cycle": cycle})
1182 cycle++
1183 select {
1184 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1185 switch uniIndication {
1186 // no activity requested (should normally not be received) - just continue waiting
1187 case cWaitReconcileFlowNoActivity:
1188 logger.Debugw(ctx, "WaitReconcileFlow no activity",
1189 log.Fields{"device-id": dh.deviceID, "rxEntries": reconciledUniVlanConfigEntries})
1190 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1191 case cWaitReconcileFlowAbortOnError:
1192 logger.Debugw(ctx, "waitReconcileFlow aborted on error",
1193 log.Fields{"device-id": dh.deviceID, "rxEntries": reconciledUniVlanConfigEntries})
1194 return
1195 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1196 case cWaitReconcileFlowAbortOnSuccess:
1197 logger.Debugw(ctx, "waitReconcileFlow aborted on success",
1198 log.Fields{"device-id": dh.deviceID, "rxEntries": reconciledUniVlanConfigEntries})
1199 return
1200 // this should be a valid UNI vlan config done indication
1201 default:
1202 if uniIndication < maxUnisPerOnu {
1203 logger.Debugw(ctx, "reconciling flows has been finished in time for this UNI",
1204 log.Fields{"device-id": dh.deviceID, "uni-id": uniIndication})
1205 if reconciledUniVlanConfigEntries, appended =
1206 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1207 waitGroup.Done()
1208 }
1209 } else {
1210 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored",
1211 log.Fields{"device-id": dh.deviceID, "uni-id": uniIndication})
1212 }
1213 } //switch uniIndication
1214
1215 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1216 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1217 log.Fields{"device-id": dh.deviceID})
1218 return
1219 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001220 }
1221}
1222
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00001223func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1224 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1225}
1226
1227func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1228 for _, ele := range slice {
1229 if ele == val {
1230 return slice, false
1231 }
1232 }
1233 return append(slice, val), true
1234}
1235
1236// sendChReconcileFinished - sends true or false on reconcileFinish channel
1237func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1238 if dh != nil { //if the object still exists (might have been already deleted in background)
1239 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1240 select {
1241 case dh.chReconcilingFinished <- success:
1242 default:
1243 }
1244 }
1245}
1246
1247// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1248func (dh *deviceHandler) SendChUniVlanConfigFinished(ctx context.Context, value uint16) {
1249 if dh != nil { //if the object still exists (might have been already deleted in background)
1250 logger.Debugw(ctx, "reconciling - send to chUniVlanConfigReconcilingDone", log.Fields{
1251 "device-id": dh.deviceID, "value": value})
1252
1253 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1254 select {
1255 case dh.chUniVlanConfigReconcilingDone <- value:
1256 default:
1257 logger.Infow(ctx, "reconciling - could not send to chUniVlanConfigReconcilingDone", log.Fields{
1258 "device-id": dh.deviceID, "value": value})
1259 }
1260 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001261}
1262
dbainbri4d3a0dc2020-12-02 00:33:42 +00001263func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
1264 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001265
dbainbri4d3a0dc2020-12-02 00:33:42 +00001266 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001267 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001268 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +00001269 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001270 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001271 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001272
1273 // deadline context to ensure completion of background routines waited for
1274 //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 +05301275 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001276 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001277
1278 pDevEntry.resetKvProcessingErrorIndication()
1279
1280 var wg sync.WaitGroup
1281 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001282 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1283 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001284
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001285 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001286 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001287}
1288
mpagenko15ff4a52021-03-02 10:09:20 +00001289//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1290// before this change here return like this was used:
1291// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1292//was and is called in background - error return does not make sense
1293func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1294 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1295 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001296 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001297 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001298 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001299 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301300 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001301 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001302 return
Himani Chawla4d908332020-08-31 12:30:20 +05301303 }
mpagenko01e726e2020-10-23 09:45:29 +00001304
1305 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001306 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001307
Holger Hildebrandt3d77f9c2022-01-12 10:45:13 +00001308 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001309 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
Holger Hildebrandt3d77f9c2022-01-12 10:45:13 +00001310 // do not set the ConnStatus here as it may conflict with the parallel setting from ONU down indication (updateInterface())
1311 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
1312 connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
ozgecanetsiae11479f2020-07-06 09:44:47 +03001313 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001314 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001315 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001316 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001317 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001318 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001319 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001320 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001321 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001322 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1323 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1324 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1325 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001326}
1327
mpagenkoc8bba412021-01-15 15:38:44 +00001328//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko9c225032021-10-15 14:26:49 +00001329// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001330func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1331 apDownloadManager *adapterDownloadManager) error {
1332 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001333 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001334
1335 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001336 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1337 if pDevEntry == nil {
1338 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1339 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1340 }
1341
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001342 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001343 var inactiveImageID uint16
1344 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1345 dh.lockUpgradeFsm.Lock()
mpagenko9c225032021-10-15 14:26:49 +00001346 //lockUpgradeFsm must be release before cancelation as this may implicitly request RemoveOnuUpgradeFsm()
1347 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001348 if dh.pOnuUpradeFsm == nil {
1349 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
mpagenko9c225032021-10-15 14:26:49 +00001350 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001351 if err == nil {
1352 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1353 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1354 "device-id": dh.deviceID, "error": err})
1355 }
1356 } else {
1357 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001358 "device-id": dh.deviceID, "error": err})
1359 }
mpagenko15ff4a52021-03-02 10:09:20 +00001360 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko9c225032021-10-15 14:26:49 +00001361 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001362 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
mpagenko9c225032021-10-15 14:26:49 +00001363 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1364 dh.upgradeCanceled = true
1365 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
mpagenko80622a52021-02-09 16:53:23 +00001366 }
mpagenko9c225032021-10-15 14:26:49 +00001367 //no effort spent anymore for the old API to automatically cancel and restart the download
1368 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001369 }
mpagenko15ff4a52021-03-02 10:09:20 +00001370 } else {
1371 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1372 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001373 }
1374 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001375 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1376 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001377 }
1378 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001379}
1380
mpagenkoc26d4c02021-05-06 14:27:57 +00001381//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1382// after the OnuImage has been downloaded to the adapter, called in background
1383func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
1384 apDownloadManager *fileDownloadManager, aImageIdentifier string) {
1385
1386 var err error
1387 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1388 if pDevEntry == nil {
1389 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1390 return
1391 }
1392
1393 var inactiveImageID uint16
1394 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1395 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
1396 "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
1397 dh.lockUpgradeFsm.Lock()
mpagenko9c225032021-10-15 14:26:49 +00001398 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1399 // but must be still locked at calling createOnuUpgradeFsm
1400 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1401 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1402 if dh.pOnuUpradeFsm != nil {
1403 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1404 // abort the current processing, running upgrades are always aborted by newer request
1405 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.deviceID})
1406 //flush the remove upgradeFsmChan channel
1407 select {
1408 case <-dh.upgradeFsmChan:
1409 logger.Debug(ctx, "flushed-upgrade-fsm-channel")
1410 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001411 }
mpagenko9c225032021-10-15 14:26:49 +00001412 dh.lockUpgradeFsm.Unlock()
1413 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1414 dh.upgradeCanceled = true
1415 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1416 }
1417 select {
1418 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
1419 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.deviceID})
1420 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1421 return
1422 case <-dh.upgradeFsmChan:
1423 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.deviceID})
1424 }
1425 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001426 }
mpagenko9c225032021-10-15 14:26:49 +00001427
1428 //here it can be assumed that no running upgrade processing exists (anymore)
1429 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
1430 // but none yet defined
1431 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1432 dh.lockUpgradeFsm.Unlock()
1433 if err == nil {
1434 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1435 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1436 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
mpagenkoc26d4c02021-05-06 14:27:57 +00001437 "device-id": dh.deviceID, "error": err})
1438 return
1439 }
mpagenko9c225032021-10-15 14:26:49 +00001440 } else {
1441 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1442 "device-id": dh.deviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001443 }
1444 return
1445 }
1446 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1447 "device-id": dh.deviceID, "error": err})
1448}
1449
1450//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001451func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1452 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001453 var err error
1454 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1455 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1456 // 2.) activation of the inactive image
1457
1458 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1459 if pDevEntry == nil {
1460 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001461 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001462 }
1463 dh.lockUpgradeFsm.RLock()
1464 if dh.pOnuUpradeFsm != nil {
1465 dh.lockUpgradeFsm.RUnlock()
1466 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1467 dh.deviceID, dh.deviceID)
1468 if getErr != nil || onuVolthaDevice == nil {
1469 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 +00001470 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001471 }
mpagenko9c225032021-10-15 14:26:49 +00001472 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1473 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.deviceID})
1474 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.deviceID)
1475 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001476 // use the OnuVendor identification from this device for the internal unique name
1477 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko9c225032021-10-15 14:26:49 +00001478 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001479 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001480 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001481 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1482 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001483 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001484 }
mpagenko183647c2021-06-08 15:25:04 +00001485 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1486 "device-id": dh.deviceID, "image-id": imageIdentifier})
mpagenko9c225032021-10-15 14:26:49 +00001487 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001488 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001489 } //else
1490 dh.lockUpgradeFsm.RUnlock()
1491
1492 // 2.) check if requested image-version equals the inactive one and start its activation
1493 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1494 var inactiveImageID uint16
1495 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1496 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1497 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
mpagenko183647c2021-06-08 15:25:04 +00001498 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001499 }
mpagenko9c225032021-10-15 14:26:49 +00001500 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001501 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
mpagenko9c225032021-10-15 14:26:49 +00001502 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001503 if err == nil {
1504 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1505 inactiveImageID, aCommitRequest); err != nil {
1506 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1507 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001508 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001509 }
1510 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1511 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko9c225032021-10-15 14:26:49 +00001512 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001513 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001514 } //else
1515 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1516 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001517 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001518}
1519
1520//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001521func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1522 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001523 var err error
1524 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1525 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1526 // 2.) commitment of the active image
1527
1528 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1529 if pDevEntry == nil {
1530 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001531 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001532 }
1533 dh.lockUpgradeFsm.RLock()
1534 if dh.pOnuUpradeFsm != nil {
1535 dh.lockUpgradeFsm.RUnlock()
1536 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1537 dh.deviceID, dh.deviceID)
1538 if getErr != nil || onuVolthaDevice == nil {
1539 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 +00001540 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001541 }
mpagenko9c225032021-10-15 14:26:49 +00001542 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1543 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.deviceID})
1544 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.deviceID)
1545 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001546 // use the OnuVendor identification from this device for the internal unique name
1547 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko9c225032021-10-15 14:26:49 +00001548 // 1.) check a started upgrade process and relay the commitment request to it
1549 // the running upgrade may be based either on the imageIdentifier (started from download)
1550 // or on the imageVersion (started from pure activation)
1551 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1552 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001553 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1554 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001555 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001556 }
mpagenko183647c2021-06-08 15:25:04 +00001557 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1558 "device-id": dh.deviceID, "image-id": imageIdentifier})
mpagenko9c225032021-10-15 14:26:49 +00001559 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001560 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001561 } //else
1562 dh.lockUpgradeFsm.RUnlock()
1563
mpagenko183647c2021-06-08 15:25:04 +00001564 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001565 var activeImageID uint16
1566 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1567 logger.Errorw(ctx, "get active image failed", log.Fields{
1568 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
mpagenko183647c2021-06-08 15:25:04 +00001569 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001570 }
mpagenko9c225032021-10-15 14:26:49 +00001571 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001572 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
mpagenko9c225032021-10-15 14:26:49 +00001573 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001574 if err == nil {
1575 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1576 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1577 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001578 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001579 }
1580 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1581 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko9c225032021-10-15 14:26:49 +00001582 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001583 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001584 } //else
1585 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1586 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001587 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001588}
1589
mpagenkoaa3afe92021-05-21 16:20:58 +00001590func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko9c225032021-10-15 14:26:49 +00001591 aVersion string) *voltha.ImageState {
1592 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001593 dh.lockUpgradeFsm.RLock()
mpagenko9c225032021-10-15 14:26:49 +00001594 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001595 if dh.pOnuUpradeFsm != nil {
mpagenko9c225032021-10-15 14:26:49 +00001596 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1597 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1598 if aVersion == dh.pLastUpgradeImageState.Version {
1599 pImageState = dh.pLastUpgradeImageState
1600 } else { //state request for an image version different from last processed image version
1601 pImageState = &voltha.ImageState{
1602 Version: aVersion,
1603 //we cannot state something concerning this version
1604 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1605 Reason: voltha.ImageState_NO_ERROR,
1606 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1607 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001608 }
1609 }
mpagenko9c225032021-10-15 14:26:49 +00001610 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001611}
1612
1613func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1614 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1615 pDeviceImageState.DeviceId = dh.deviceID
mpagenko7455fd42021-06-10 16:25:55 +00001616 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001617 dh.lockUpgradeFsm.RLock()
1618 if dh.pOnuUpradeFsm != nil {
mpagenko9c225032021-10-15 14:26:49 +00001619 // so then we cancel the upgrade operation
1620 // but before we still request the actual upgrade states for the direct response
1621 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
mpagenkoaa3afe92021-05-21 16:20:58 +00001622 dh.lockUpgradeFsm.RUnlock()
mpagenko9c225032021-10-15 14:26:49 +00001623 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
mpagenkoaa3afe92021-05-21 16:20:58 +00001624 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
mpagenko9c225032021-10-15 14:26:49 +00001625 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1626 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1627 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
1628 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1629 dh.upgradeCanceled = true
1630 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1631 }
1632 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001633 } else {
1634 dh.lockUpgradeFsm.RUnlock()
mpagenko9c225032021-10-15 14:26:49 +00001635 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1636 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1637 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1638 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1639 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1640 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001641 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1642 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko9c225032021-10-15 14:26:49 +00001643 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1644 //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 +00001645 }
1646}
1647
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001648func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1649
1650 var onuImageStatus *OnuImageStatus
1651
1652 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1653 if pDevEntry != nil {
1654 onuImageStatus = NewOnuImageStatus(pDevEntry)
1655 pDevEntry.mutexOnuImageStatus.Lock()
1656 pDevEntry.pOnuImageStatus = onuImageStatus
1657 pDevEntry.mutexOnuImageStatus.Unlock()
1658
1659 } else {
1660 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1661 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1662 }
1663 images, err := onuImageStatus.getOnuImageStatus(ctx)
1664 pDevEntry.mutexOnuImageStatus.Lock()
1665 pDevEntry.pOnuImageStatus = nil
1666 pDevEntry.mutexOnuImageStatus.Unlock()
1667 return images, err
1668}
1669
Himani Chawla6d2ae152020-09-02 13:11:20 +05301670// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001671// #####################################################################################
1672
1673// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301674// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001675
dbainbri4d3a0dc2020-12-02 00:33:42 +00001676func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1677 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 +00001678}
1679
1680// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001681func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001682
dbainbri4d3a0dc2020-12-02 00:33:42 +00001683 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001684 var err error
1685
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001686 // populate what we know. rest comes later after mib sync
1687 dh.device.Root = false
1688 dh.device.Vendor = "OpenONU"
1689 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001690 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001691 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001692
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001693 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001694
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001695 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001696 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1697 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301698 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001699 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001700 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001701 log.Fields{"device-id": dh.deviceID})
1702 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001703
Himani Chawla4d908332020-08-31 12:30:20 +05301704 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001705 dh.ponPortNumber = dh.device.ParentPortNo
1706
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001707 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1708 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1709 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001710 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001711 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301712 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001713
1714 /*
1715 self._pon = PonPort.create(self, self._pon_port_number)
1716 self._pon.add_peer(self.parent_id, self._pon_port_number)
1717 self.logger.debug('adding-pon-port-to-agent',
1718 type=self._pon.get_port().type,
1719 admin_state=self._pon.get_port().admin_state,
1720 oper_status=self._pon.get_port().oper_status,
1721 )
1722 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001723 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001724 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001725 var ponPortNo uint32 = 1
1726 if dh.ponPortNumber != 0 {
1727 ponPortNo = dh.ponPortNumber
1728 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001729
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001730 pPonPort := &voltha.Port{
1731 PortNo: ponPortNo,
1732 Label: fmt.Sprintf("pon-%d", ponPortNo),
1733 Type: voltha.Port_PON_ONU,
1734 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301735 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001736 PortNo: ponPortNo}}, // Peer port is parent's port number
1737 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001738 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1739 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001740 e.Cancel(err)
1741 return
1742 }
1743 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001744 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001745 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001746 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001747}
1748
1749// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001750func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001751
dbainbri4d3a0dc2020-12-02 00:33:42 +00001752 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001753 var err error
1754 /*
1755 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1756 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1757 return nil
1758 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001759 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1760 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001761 e.Cancel(err)
1762 return
1763 }
1764
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001765 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001766 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001767 // reconcilement will be continued after mib download is done
1768 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001769
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001770 /*
1771 ############################################################################
1772 # Setup Alarm handler
1773 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1774 device.serial_number)
1775 ############################################################################
1776 # Setup PM configuration for this device
1777 # Pass in ONU specific options
1778 kwargs = {
1779 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1780 'heartbeat': self.heartbeat,
1781 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1782 }
1783 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1784 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1785 self.logical_device_id, device.serial_number,
1786 grouped=True, freq_override=False, **kwargs)
1787 pm_config = self._pm_metrics.make_proto()
1788 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1789 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1790 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1791
1792 # Note, ONU ID and UNI intf set in add_uni_port method
1793 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1794 ani_ports=[self._pon])
1795
1796 # Code to Run OMCI Test Action
1797 kwargs_omci_test_action = {
1798 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1799 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1800 }
1801 serial_number = device.serial_number
1802 self._test_request = OmciTestRequest(self.core_proxy,
1803 self.omci_agent, self.device_id,
1804 AniG, serial_number,
1805 self.logical_device_id,
1806 exclusive=False,
1807 **kwargs_omci_test_action)
1808
1809 self.enabled = True
1810 else:
1811 self.logger.info('onu-already-activated')
1812 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001813
dbainbri4d3a0dc2020-12-02 00:33:42 +00001814 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001815}
1816
1817// doStateConnected get the device info and update to voltha core
1818// for comparison of the original method (not that easy to uncomment): compare here:
1819// voltha-openolt-adapter/adaptercore/device_handler.go
1820// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001821func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001822
dbainbri4d3a0dc2020-12-02 00:33:42 +00001823 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301824 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001825 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001826 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001827}
1828
1829// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001830func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001831
dbainbri4d3a0dc2020-12-02 00:33:42 +00001832 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301833 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001834 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001835 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001836
1837 /*
1838 // Synchronous call to update device state - this method is run in its own go routine
1839 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1840 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001841 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 +00001842 return err
1843 }
1844 return nil
1845 */
1846}
1847
1848// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001849func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001850
dbainbri4d3a0dc2020-12-02 00:33:42 +00001851 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001852 var err error
1853
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001854 device := dh.device
1855 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001856 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001857 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001858 e.Cancel(err)
1859 return
1860 }
1861
1862 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001863 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001864 /*
1865 // Update the all ports state on that device to disable
1866 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001867 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001868 return er
1869 }
1870
1871 //Update the device oper state and connection status
1872 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1873 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1874 dh.device = cloned
1875
1876 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001877 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001878 return er
1879 }
1880
1881 //get the child device for the parent device
1882 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1883 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001884 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001885 return err
1886 }
1887 for _, onuDevice := range onuDevices.Items {
1888
1889 // Update onu state as down in onu adapter
1890 onuInd := oop.OnuIndication{}
1891 onuInd.OperState = "down"
1892 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1893 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1894 if er != nil {
1895 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001896 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001897 //Do not return here and continue to process other ONUs
1898 }
1899 }
1900 // * Discovered ONUs entries need to be cleared , since after OLT
1901 // is up, it starts sending discovery indications again* /
1902 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001903 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001904 return nil
1905 */
Himani Chawla4d908332020-08-31 12:30:20 +05301906 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001907 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001908 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001909}
1910
Himani Chawla6d2ae152020-09-02 13:11:20 +05301911// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001912// #################################################################################
1913
1914// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301915// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001916
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001917//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001918func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001919 dh.lockDevice.RLock()
1920 pOnuDeviceEntry := dh.pOnuOmciDevice
1921 if aWait && pOnuDeviceEntry == nil {
1922 //keep the read sema short to allow for subsequent write
1923 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001924 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001925 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1926 // so it might be needed to wait here for that event with some timeout
1927 select {
1928 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001929 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001930 return nil
1931 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001932 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001933 // if written now, we can return the written value without sema
1934 return dh.pOnuOmciDevice
1935 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001936 }
mpagenko3af1f032020-06-10 08:53:41 +00001937 dh.lockDevice.RUnlock()
1938 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001939}
1940
Himani Chawla6d2ae152020-09-02 13:11:20 +05301941//setOnuDeviceEntry sets the ONU device entry within the handler
1942func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001943 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001944 dh.lockDevice.Lock()
1945 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001946 dh.pOnuOmciDevice = apDeviceEntry
1947 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001948 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301949 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001950 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001951}
1952
Himani Chawla6d2ae152020-09-02 13:11:20 +05301953//addOnuDeviceEntry creates a new ONU device or returns the existing
1954func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001955 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001956
dbainbri4d3a0dc2020-12-02 00:33:42 +00001957 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001958 if deviceEntry == nil {
1959 /* costum_me_map in python code seems always to be None,
1960 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1961 /* also no 'clock' argument - usage open ...*/
1962 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001963 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001964 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001965 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301966 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001967 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001968 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001969 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001970 // fire deviceEntry ready event to spread to possibly waiting processing
1971 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001972 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001973 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001974 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001975 }
1976 // might be updated with some error handling !!!
1977 return nil
1978}
1979
dbainbri4d3a0dc2020-12-02 00:33:42 +00001980func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1981 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001982 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1983
1984 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001985
dbainbri4d3a0dc2020-12-02 00:33:42 +00001986 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001987 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001988 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001989 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1990 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001991 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001992 if err := dh.storePersistentData(ctx); err != nil {
1993 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001994 log.Fields{"device-id": dh.deviceID, "err": err})
1995 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001996 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001997 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001998 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001999 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
2000 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002001 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002002 }
2003 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002004 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002005 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002006
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002007 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002008 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002009 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002010 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 +00002011 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00002012 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002013 } else {
2014 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002015 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002016 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002017 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
2018 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
2019 // 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 +00002020 // 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 +00002021 // so let's just try to keep it simple ...
2022 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00002023 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002024 if err != nil || device == nil {
2025 //TODO: needs to handle error scenarios
2026 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
2027 return errors.New("Voltha Device not found")
2028 }
2029 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002030
dbainbri4d3a0dc2020-12-02 00:33:42 +00002031 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002032 return err
mpagenko3af1f032020-06-10 08:53:41 +00002033 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002034
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002035 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002036
2037 /* this might be a good time for Omci Verify message? */
2038 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002039 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00002040 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00002041 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002042 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002043
2044 /* give the handler some time here to wait for the OMCi verification result
2045 after Timeout start and try MibUpload FSM anyway
2046 (to prevent stopping on just not supported OMCI verification from ONU) */
2047 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002048 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00002049 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002050 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00002051 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002052 }
2053
2054 /* In py code it looks earlier (on activate ..)
2055 # Code to Run OMCI Test Action
2056 kwargs_omci_test_action = {
2057 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2058 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2059 }
2060 serial_number = device.serial_number
2061 self._test_request = OmciTestRequest(self.core_proxy,
2062 self.omci_agent, self.device_id,
2063 AniG, serial_number,
2064 self.logical_device_id,
2065 exclusive=False,
2066 **kwargs_omci_test_action)
2067 ...
2068 # Start test requests after a brief pause
2069 if not self._test_request_started:
2070 self._test_request_started = True
2071 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2072 reactor.callLater(tststart, self._test_request.start_collector)
2073
2074 */
2075 /* which is then: in omci_test_request.py : */
2076 /*
2077 def start_collector(self, callback=None):
2078 """
2079 Start the collection loop for an adapter if the frequency > 0
2080
2081 :param callback: (callable) Function to call to collect PM data
2082 """
2083 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2084 if callback is None:
2085 callback = self.perform_test_omci
2086
2087 if self.lc is None:
2088 self.lc = LoopingCall(callback)
2089
2090 if self.default_freq > 0:
2091 self.lc.start(interval=self.default_freq / 10)
2092
2093 def perform_test_omci(self):
2094 """
2095 Perform the initial test request
2096 """
2097 ani_g_entities = self._device.configuration.ani_g_entities
2098 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2099 is not None else None
2100 self._entity_id = ani_g_entities_ids[0]
2101 self.logger.info('perform-test', entity_class=self._entity_class,
2102 entity_id=self._entity_id)
2103 try:
2104 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2105 result = yield self._device.omci_cc.send(frame)
2106 if not result.fields['omci_message'].fields['success_code']:
2107 self.logger.info('Self-Test Submitted Successfully',
2108 code=result.fields[
2109 'omci_message'].fields['success_code'])
2110 else:
2111 raise TestFailure('Test Failure: {}'.format(
2112 result.fields['omci_message'].fields['success_code']))
2113 except TimeoutError as e:
2114 self.deferred.errback(failure.Failure(e))
2115
2116 except Exception as e:
2117 self.logger.exception('perform-test-Error', e=e,
2118 class_id=self._entity_class,
2119 entity_id=self._entity_id)
2120 self.deferred.errback(failure.Failure(e))
2121
2122 */
2123
2124 // PM related heartbeat??? !!!TODO....
2125 //self._heartbeat.enabled = True
2126
mpagenko1cc3cb42020-07-27 15:24:38 +00002127 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2128 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2129 * 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 +05302130 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002131 */
2132 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00002133 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002134 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002135 if pMibUlFsm.Is(ulStDisabled) {
2136 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002137 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 +00002138 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302139 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002140 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302141 //Determine ONU status and start/re-start MIB Synchronization tasks
2142 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00002143 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05302144 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002145 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 +00002146 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002147 }
Himani Chawla4d908332020-08-31 12:30:20 +05302148 } else {
2149 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002150 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 +00002151 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302152 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002153 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002154 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002155 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002156 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002157 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002158 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002159 }
2160 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002161 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002162 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002163 }
2164 return nil
2165}
2166
dbainbri4d3a0dc2020-12-02 00:33:42 +00002167func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00002168 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002169 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002170 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002171 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002172
mpagenko900ee4b2020-10-12 11:56:34 +00002173 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2174 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2175 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002176 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002177 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00002178 log.Fields{"device-id": dh.deviceID, "error": err})
2179 // abort: system behavior is just unstable ...
2180 return err
2181 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002182 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002183 _ = 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 +00002184
2185 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
Holger Hildebrandt3d77f9c2022-01-12 10:45:13 +00002186 //stop the device entry to allow for all system event transfers again
dbainbri4d3a0dc2020-12-02 00:33:42 +00002187 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002188 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002189 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002190 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002191 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002192 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002193
2194 //TODO!!! remove existing traffic profiles
2195 /* from py code, if TP's exist, remove them - not yet implemented
2196 self._tp = dict()
2197 # Let TP download happen again
2198 for uni_id in self._tp_service_specific_task:
2199 self._tp_service_specific_task[uni_id].clear()
2200 for uni_id in self._tech_profile_download_done:
2201 self._tech_profile_download_done[uni_id].clear()
2202 */
2203
dbainbri4d3a0dc2020-12-02 00:33:42 +00002204 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002205
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002206 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002207
dbainbri4d3a0dc2020-12-02 00:33:42 +00002208 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002209 // abort: system behavior is just unstable ...
2210 return err
2211 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002212 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002213 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002214 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00002215 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002216 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002217 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00002218 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002219 // abort: system behavior is just unstable ...
2220 return err
2221 }
2222 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002223 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002224 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002225 return nil
2226}
2227
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002228func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002229 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2230 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2231 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2232 // and using the stop/reset event should never harm
2233
dbainbri4d3a0dc2020-12-02 00:33:42 +00002234 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002235 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002236 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002237 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2238 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002239 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002240 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002241 }
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002242 pDevEntry.mutexOnuImageStatus.RLock()
2243 if pDevEntry.pOnuImageStatus != nil {
2244 pDevEntry.pOnuImageStatus.CancelProcessing(ctx)
2245 }
2246 pDevEntry.mutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002247
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002248 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002249 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002250 }
2251 //MibDownload may run
2252 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2253 if pMibDlFsm != nil {
2254 _ = pMibDlFsm.Event(dlEvReset)
2255 }
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00002256 //stop any deviceHandler reconcile processing (if running)
2257 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002258 //port lock/unlock FSM's may be active
2259 if dh.pUnlockStateFsm != nil {
2260 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2261 }
2262 if dh.pLockStateFsm != nil {
2263 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2264 }
2265 //techProfile related PonAniConfigFsm FSM may be active
2266 if dh.pOnuTP != nil {
2267 // should always be the case here
2268 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
2269 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08002270 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00002271 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002272 }
mpagenko900ee4b2020-10-12 11:56:34 +00002273 }
2274 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002275 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002276 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00002277 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
2278 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002279 dh.lockVlanConfig.RUnlock()
2280 //reset of all Fsm is always accompanied by global persistency data removal
2281 // no need to remove specific data
Holger Hildebrandt72eaab72021-11-05 08:54:59 +00002282 pVlanFilterFsm.RequestClearPersistency(ctx, false)
mpagenko7d6bb022021-03-11 15:07:55 +00002283 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002284 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002285 } else {
2286 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002287 }
2288 }
2289 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002290 if dh.getCollectorIsRunning() {
2291 // Stop collector routine
2292 dh.stopCollector <- true
2293 }
Himani Chawla1472c682021-03-17 17:11:14 +05302294 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302295 dh.stopAlarmManager <- true
2296 }
2297
mpagenko80622a52021-02-09 16:53:23 +00002298 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00002299 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002300 dh.lockUpgradeFsm.RLock()
mpagenko9c225032021-10-15 14:26:49 +00002301 lopOnuUpradeFsm := dh.pOnuUpradeFsm
2302 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002303 dh.lockUpgradeFsm.RUnlock()
mpagenko9c225032021-10-15 14:26:49 +00002304 if lopOnuUpradeFsm != nil {
2305 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2306 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2307 // (even though it may also run into direct cancellation, a bit hard to verify here)
2308 // so don't set 'dh.upgradeCanceled = true' here!
2309 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2310 }
2311 }
mpagenko80622a52021-02-09 16:53:23 +00002312
mpagenko7d6bb022021-03-11 15:07:55 +00002313 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002314 return nil
2315}
2316
dbainbri4d3a0dc2020-12-02 00:33:42 +00002317func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2318 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 +05302319
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002320 // store persistent data collected during MIB upload processing
2321 if err := dh.storePersistentData(ctx); err != nil {
2322 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2323 log.Fields{"device-id": dh.deviceID, "err": err})
2324 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002325 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002326 dh.addAllUniPorts(ctx)
2327
mpagenkoa40e99a2020-11-17 13:50:39 +00002328 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2329 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2330 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2331 * disable/enable toggling here to allow traffic
2332 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2333 * like the py comment says:
2334 * # start by locking all the unis till mib sync and initial mib is downloaded
2335 * # this way we can capture the port down/up events when we are ready
2336 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302337
mpagenkoa40e99a2020-11-17 13:50:39 +00002338 // Init Uni Ports to Admin locked state
2339 // *** should generate UniLockStateDone event *****
2340 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002341 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002342 } else { //LockStateFSM already init
2343 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002344 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002345 }
2346}
2347
dbainbri4d3a0dc2020-12-02 00:33:42 +00002348func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2349 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302350 /* Mib download procedure -
2351 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2352 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002353 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002354 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002355 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002356 return
2357 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302358 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2359 if pMibDlFsm != nil {
2360 if pMibDlFsm.Is(dlStDisabled) {
2361 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002362 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 +05302363 // maybe try a FSM reset and then again ... - TODO!!!
2364 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002365 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302366 // maybe use more specific states here for the specific download steps ...
2367 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002368 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302369 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002370 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302371 //Begin MIB data download (running autonomously)
2372 }
2373 }
2374 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002375 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002376 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302377 // maybe try a FSM reset and then again ... - TODO!!!
2378 }
2379 /***** Mib download started */
2380 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002381 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302382 }
2383}
2384
dbainbri4d3a0dc2020-12-02 00:33:42 +00002385func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2386 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302387 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002388 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002389 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002390 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002391 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2392 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2393 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2394 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002395 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302396 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
2397 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002398 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302399 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002400 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302401 }
2402 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002403 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302404 log.Fields{"device-id": dh.deviceID})
2405 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002406 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002407
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002408 if !dh.getCollectorIsRunning() {
2409 // Start PM collector routine
2410 go dh.startCollector(ctx)
2411 }
2412 if !dh.getAlarmManagerIsRunning(ctx) {
2413 go dh.startAlarmManager(ctx)
2414 }
2415
Girish Gowdrae0140f02021-02-02 16:55:09 -08002416 // Initialize classical L2 PM Interval Counters
2417 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2418 // There is no way we should be landing here, but if we do then
2419 // there is nothing much we can do about this other than log error
2420 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2421 }
2422
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002423 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002424
2425 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2426 if pDevEntry == nil {
2427 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2428 return
2429 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002430 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002431 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002432 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002433 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2434 log.Fields{"device-id": dh.deviceID})
2435 go dh.reconcileDeviceTechProf(ctx)
2436 // reconcilement will be continued after ani config is done
2437 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002438 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002439 // *** should generate UniUnlockStateDone event *****
2440 if dh.pUnlockStateFsm == nil {
2441 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2442 } else { //UnlockStateFSM already init
2443 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2444 dh.runUniLockFsm(ctx, false)
2445 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302446 }
2447}
2448
dbainbri4d3a0dc2020-12-02 00:33:42 +00002449func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2450 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302451
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002452 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002453 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002454 raisedTs := time.Now().Unix()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002455 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2456 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002457 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002458 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002459 return
2460 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002461 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002462 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002463 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002464 if err := dh.storePersistentData(ctx); err != nil {
2465 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002466 log.Fields{"device-id": dh.deviceID, "err": err})
2467 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302468 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002469 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 +05302470 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002471 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002472 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302473 }
2474}
2475
dbainbri4d3a0dc2020-12-02 00:33:42 +00002476func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
Holger Hildebrandt3d77f9c2022-01-12 10:45:13 +00002477 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
mpagenko900ee4b2020-10-12 11:56:34 +00002478 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
Holger Hildebrandt3d77f9c2022-01-12 10:45:13 +00002479 // disable device should have no impact on ConnStatus
2480 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
2481 connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
2482 voltha.OperStatus_UNKNOWN); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002483 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002484 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002485 }
2486
dbainbri4d3a0dc2020-12-02 00:33:42 +00002487 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002488 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002489 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002490
2491 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002492 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002493
dbainbri4d3a0dc2020-12-02 00:33:42 +00002494 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002495 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002496 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002497 return
2498 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002499 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002500 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002501 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002502 if err := dh.storePersistentData(ctx); err != nil {
2503 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002504 log.Fields{"device-id": dh.deviceID, "err": err})
2505 }
mpagenko900ee4b2020-10-12 11:56:34 +00002506}
2507
dbainbri4d3a0dc2020-12-02 00:33:42 +00002508func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2509 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002510 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002511 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002512 voltha.OperStatus_ACTIVE); err != nil {
2513 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002514 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002515 }
2516
dbainbri4d3a0dc2020-12-02 00:33:42 +00002517 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002518 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002519 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002520 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002521
2522 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002523 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002524
dbainbri4d3a0dc2020-12-02 00:33:42 +00002525 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002526 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002527 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002528 return
2529 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002530 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002531 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002532 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002533 if err := dh.storePersistentData(ctx); err != nil {
2534 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002535 log.Fields{"device-id": dh.deviceID, "err": err})
2536 }
mpagenko900ee4b2020-10-12 11:56:34 +00002537}
2538
Holger Hildebrandtda15a092022-01-07 15:30:49 +00002539func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2540 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2541 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.deviceID})
2542 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
2543 voltha.OperStatus_FAILED); err != nil {
2544 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
2545 }
2546}
2547
dbainbri4d3a0dc2020-12-02 00:33:42 +00002548func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002549 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002550 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002551 // attention: the device reason update is done based on ONU-UNI-Port related activity
2552 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002553 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002554 // 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 +00002555 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302556 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002557 if dh.isReconciling() {
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00002558 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
2559 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
2560 dh.mutexReconcilingFirstPassFlag.Lock()
2561 if dh.reconcilingFirstPass {
2562 logger.Debugw(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.deviceID})
2563 dh.reconcilingFirstPass = false
2564 go dh.reconcileDeviceFlowConfig(ctx)
2565 }
2566 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00002567 }
2568 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002569 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002570 // attention: the device reason update is done based on ONU-UNI-Port related activity
2571 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002572 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002573 // 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 +00002574 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002575 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002576 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302577}
2578
dbainbri4d3a0dc2020-12-02 00:33:42 +00002579func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2580 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002581 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302582 // attention: the device reason update is done based on ONU-UNI-Port related activity
2583 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302584
mpagenkof1fc3862021-02-16 10:09:52 +00002585 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002586 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002587 // which may be the case from some previous actvity on another UNI Port of the ONU
2588 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002589 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
mpagenkofc4f56e2020-11-04 17:17:49 +00002590 }
2591 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002592 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002593 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002594 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002595 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302596 }
mpagenkof1fc3862021-02-16 10:09:52 +00002597
2598 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2599 //events that request KvStore write
2600 if err := dh.storePersistentData(ctx); err != nil {
2601 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2602 log.Fields{"device-id": dh.deviceID, "err": err})
2603 }
2604 } else {
2605 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2606 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002607 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302608}
2609
Himani Chawla6d2ae152020-09-02 13:11:20 +05302610//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002611func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302612 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002613 case MibDatabaseSync:
2614 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002615 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002616 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002617 case UniLockStateDone:
2618 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002619 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002620 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002621 case MibDownloadDone:
2622 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002623 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002624 }
2625 case UniUnlockStateDone:
2626 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002627 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002628 }
mpagenko900ee4b2020-10-12 11:56:34 +00002629 case UniEnableStateDone:
2630 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002631 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002632 }
Holger Hildebrandtda15a092022-01-07 15:30:49 +00002633 case UniEnableStateFailed:
2634 {
2635 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2636 }
mpagenko900ee4b2020-10-12 11:56:34 +00002637 case UniDisableStateDone:
2638 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002639 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002640 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002641 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002642 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002643 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002644 }
mpagenkof1fc3862021-02-16 10:09:52 +00002645 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002646 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002647 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002648 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002649 default:
2650 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002651 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002652 }
2653 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002654}
2655
dbainbri4d3a0dc2020-12-02 00:33:42 +00002656func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002657 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002658 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302659 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002660 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002661 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002662 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302663 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002664 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002665 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002666 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002667 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002668 //store UniPort with the System-PortNumber key
2669 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002670 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002671 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002672 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2673 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002674 } //error logging already within UniPort method
2675 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002676 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002677 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002678 }
2679 }
2680}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002681
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002682func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2683 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2684 if pDevEntry == nil {
2685 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2686 return
2687 }
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00002688 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002689 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2690 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2691 for _, mgmtEntityID := range pptpInstKeys {
2692 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2693 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00002694 dh.addUniPort(ctx, mgmtEntityID, uniCnt, uniPPTP)
2695 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002696 }
2697 } else {
2698 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2699 }
2700 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2701 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2702 for _, mgmtEntityID := range veipInstKeys {
2703 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2704 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00002705 dh.addUniPort(ctx, mgmtEntityID, uniCnt, uniVEIP)
2706 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002707 }
2708 } else {
2709 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2710 }
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00002711 if uniCnt == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002712 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2713 }
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00002714 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
2715 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002716}
2717
mpagenko3af1f032020-06-10 08:53:41 +00002718// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002719func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002720 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302721 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002722 // with following remark:
2723 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2724 // # load on the core
2725
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002726 // 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 +00002727
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002728 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002729 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002730 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002731 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302732 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002733 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002734 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002735 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 +00002736 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002737 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002738 }
mpagenko3af1f032020-06-10 08:53:41 +00002739 }
2740 }
2741}
2742
2743// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002744func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002745 // compare enableUniPortStateUpdate() above
2746 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2747 for uniNo, uniPort := range dh.uniEntityMap {
2748 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002749
2750 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002751 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302752 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002753 if !dh.isReconciling() {
2754 //maybe also use getter functions on uniPort - perhaps later ...
2755 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2756 } else {
2757 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2758 }
2759
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002760 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002761 }
2762}
2763
2764// ONU_Active/Inactive announcement on system KAFKA bus
2765// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002766func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002767 var de voltha.DeviceEvent
2768 eventContext := make(map[string]string)
2769 //Populating event context
2770 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002771 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002772 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002773 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302774 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002775 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 +00002776 }
2777 oltSerialNumber := parentDevice.SerialNumber
2778
2779 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2780 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2781 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302782 eventContext["olt-serial-number"] = oltSerialNumber
2783 eventContext["device-id"] = aDeviceID
2784 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002785 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
2786 if deviceEntry := dh.getOnuDeviceEntry(ctx, false); deviceEntry != nil {
2787 deviceEntry.mutexPersOnuConfig.RLock()
2788 eventContext["equipment-id"] = deviceEntry.sOnuPersistentData.PersEquipmentID
2789 deviceEntry.mutexPersOnuConfig.RUnlock()
2790 eventContext["software-version"] = deviceEntry.getActiveImageVersion(ctx)
2791 deviceEntry.mutexPersOnuConfig.RLock()
2792 eventContext["vendor"] = deviceEntry.sOnuPersistentData.PersVendorID
2793 deviceEntry.mutexPersOnuConfig.RUnlock()
2794 eventContext["inactive-software-version"] = deviceEntry.getInactiveImageVersion(ctx)
2795 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2796 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2797 } else {
2798 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2799 log.Fields{"device-id": aDeviceID})
2800 return
2801 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002802
2803 /* Populating device event body */
2804 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302805 de.ResourceId = aDeviceID
2806 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002807 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2808 de.Description = fmt.Sprintf("%s Event - %s - %s",
2809 cEventObjectType, cOnuActivatedEvent, "Raised")
2810 } else {
2811 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2812 de.Description = fmt.Sprintf("%s Event - %s - %s",
2813 cEventObjectType, cOnuActivatedEvent, "Cleared")
2814 }
2815 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002816 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2817 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302818 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002819 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002820 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302821 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002822}
2823
Himani Chawla4d908332020-08-31 12:30:20 +05302824// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002825func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002826 chLSFsm := make(chan Message, 2048)
2827 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302828 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002829 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002830 sFsmName = "LockStateFSM"
2831 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002832 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002833 sFsmName = "UnLockStateFSM"
2834 }
mpagenko3af1f032020-06-10 08:53:41 +00002835
dbainbri4d3a0dc2020-12-02 00:33:42 +00002836 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002837 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002838 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002839 return
2840 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002841 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002842 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002843 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302844 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002845 dh.pLockStateFsm = pLSFsm
2846 } else {
2847 dh.pUnlockStateFsm = pLSFsm
2848 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002849 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002850 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002851 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002852 }
2853}
2854
2855// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002856func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002857 /* Uni Port lock/unlock procedure -
2858 ***** should run via 'adminDone' state and generate the argument requested event *****
2859 */
2860 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302861 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002862 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2863 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2864 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002865 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302866 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002867 }
2868 } else {
2869 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2870 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2871 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002872 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302873 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002874 }
2875 }
2876 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002877 if pLSStatemachine.Is(uniStDisabled) {
2878 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002879 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002880 // maybe try a FSM reset and then again ... - TODO!!!
2881 } else {
2882 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002883 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002884 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002885 }
2886 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002887 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002888 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002889 // maybe try a FSM reset and then again ... - TODO!!!
2890 }
2891 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002892 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002893 // maybe try a FSM reset and then again ... - TODO!!!
2894 }
2895}
2896
mpagenko80622a52021-02-09 16:53:23 +00002897// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko9c225032021-10-15 14:26:49 +00002898// precondition: lockUpgradeFsm is already locked from caller of this function
mpagenko15ff4a52021-03-02 10:09:20 +00002899func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002900 chUpgradeFsm := make(chan Message, 2048)
2901 var sFsmName = "OnuSwUpgradeFSM"
2902 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002903 if apDevEntry.PDevOmciCC == nil {
2904 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2905 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002906 }
mpagenko15ff4a52021-03-02 10:09:20 +00002907 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002908 sFsmName, chUpgradeFsm)
2909 if dh.pOnuUpradeFsm != nil {
2910 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2911 if pUpgradeStatemachine != nil {
2912 if pUpgradeStatemachine.Is(upgradeStDisabled) {
2913 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2914 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2915 // maybe try a FSM reset and then again ... - TODO!!!
2916 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2917 }
mpagenko9c225032021-10-15 14:26:49 +00002918 /***** Upgrade FSM started */
2919 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2920 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
2921 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2922 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002923 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2924 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2925 } else {
2926 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2927 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2928 // maybe try a FSM reset and then again ... - TODO!!!
2929 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2930 }
2931 } else {
2932 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2933 // maybe try a FSM reset and then again ... - TODO!!!
2934 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2935 }
2936 } else {
2937 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2938 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2939 }
2940 return nil
2941}
2942
2943// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
mpagenko9c225032021-10-15 14:26:49 +00002944func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002945 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2946 "device-id": dh.deviceID})
2947 dh.lockUpgradeFsm.Lock()
mpagenko9c225032021-10-15 14:26:49 +00002948 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2949 dh.upgradeCanceled = false //cancelation done
2950 dh.pLastUpgradeImageState = apImageState
2951 dh.lockUpgradeFsm.Unlock()
2952 //signal upgradeFsm removed using non-blocking channel send
2953 select {
2954 case dh.upgradeFsmChan <- struct{}{}:
2955 default:
2956 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
2957 "device-id": dh.deviceID})
2958 }
mpagenko80622a52021-02-09 16:53:23 +00002959}
2960
mpagenko15ff4a52021-03-02 10:09:20 +00002961// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2962func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2963 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2964 if pDevEntry == nil {
2965 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2966 return
2967 }
2968
2969 dh.lockUpgradeFsm.RLock()
mpagenko9c225032021-10-15 14:26:49 +00002970 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00002971 if dh.pOnuUpradeFsm != nil {
mpagenko9c225032021-10-15 14:26:49 +00002972 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
2973 dh.lockUpgradeFsm.RUnlock()
2974 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.deviceID})
2975 return
2976 }
mpagenko15ff4a52021-03-02 10:09:20 +00002977 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2978 if pUpgradeStatemachine != nil {
2979 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2980 // (some manual forced commit could do without)
mpagenko1f8e8822021-06-25 14:10:21 +00002981 upgradeState := pUpgradeStatemachine.Current()
2982 if (upgradeState == upgradeStWaitForCommit) ||
2983 (upgradeState == upgradeStRequestingActivate) {
2984 // also include upgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00002985 // 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 +00002986 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00002987 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
2988 if errImg != nil {
mpagenko9c225032021-10-15 14:26:49 +00002989 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00002990 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
2991 log.Fields{"device-id": dh.deviceID})
mpagenko9c225032021-10-15 14:26:49 +00002992 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2993 dh.upgradeCanceled = true
2994 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2995 }
mpagenko15ff4a52021-03-02 10:09:20 +00002996 return
2997 }
mpagenko9c225032021-10-15 14:26:49 +00002998 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00002999 if activeImageID == dh.pOnuUpradeFsm.inactiveImageMeID {
3000 if (upgradeState == upgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
3001 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
3002 if err := pUpgradeStatemachine.Event(upgradeEvActivationDone); err != nil {
3003 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
3004 return
3005 }
3006 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
3007 "state": upgradeState, "device-id": dh.deviceID})
3008 } else {
3009 //FSM in waitForCommit or (upgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3010 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
3011 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
3012 return
3013 }
3014 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
3015 "state": upgradeState, "device-id": dh.deviceID})
3016 }
3017 } else {
3018 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit/on ActivateResponse, but load did not start with expected image Id",
3019 log.Fields{"device-id": dh.deviceID})
mpagenko9c225032021-10-15 14:26:49 +00003020 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3021 dh.upgradeCanceled = true
3022 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3023 }
mpagenko1f8e8822021-06-25 14:10:21 +00003024 }
mpagenko15ff4a52021-03-02 10:09:20 +00003025 return
3026 }
mpagenko9c225032021-10-15 14:26:49 +00003027 dh.lockUpgradeFsm.RUnlock()
3028 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3029 log.Fields{"device-id": dh.deviceID})
3030 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3031 dh.upgradeCanceled = true
3032 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3033 }
3034 return
3035 }
3036 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3037 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3038 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3039 if dh.pOnuUpradeFsm.inactiveImageMeID == activeImageID {
3040 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3041 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
3042 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003043 }
mpagenko15ff4a52021-03-02 10:09:20 +00003044 }
3045 }
3046 } else {
3047 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
3048 }
mpagenko9c225032021-10-15 14:26:49 +00003049 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003050}
3051
Himani Chawla6d2ae152020-09-02 13:11:20 +05303052//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00003053func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003054
3055 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00003056 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003057 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003058 kvbackend := &db.Backend{
3059 Client: dh.pOpenOnuAc.kvClient,
3060 StoreType: dh.pOpenOnuAc.KVStoreType,
3061 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003062 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003063 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3064 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003065
mpagenkoaf801632020-07-03 10:00:42 +00003066 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003067}
dbainbri4d3a0dc2020-12-02 00:33:42 +00003068func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05303069 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003070
mpagenkodff5dda2020-08-28 11:52:01 +00003071 for _, field := range flow.GetOfbFields(apFlowItem) {
3072 switch field.Type {
3073 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3074 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003075 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003076 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3077 }
mpagenko01e726e2020-10-23 09:45:29 +00003078 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003079 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3080 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303081 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00003082 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303083 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3084 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003085 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3086 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003087 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
3088 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303089 return
mpagenkodff5dda2020-08-28 11:52:01 +00003090 }
3091 }
mpagenko01e726e2020-10-23 09:45:29 +00003092 */
mpagenkodff5dda2020-08-28 11:52:01 +00003093 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3094 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303095 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003096 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303097 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003098 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303099 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003100 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003101 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303102 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003103 }
3104 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3105 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303106 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00003107 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003108 "PCP": loAddPcp})
3109 }
3110 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3111 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003112 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003113 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3114 }
3115 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3116 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003117 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003118 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3119 }
3120 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3121 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003122 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003123 "IPv4-DST": field.GetIpv4Dst()})
3124 }
3125 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3126 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003127 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003128 "IPv4-SRC": field.GetIpv4Src()})
3129 }
3130 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3131 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003132 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003133 "Metadata": field.GetTableMetadata()})
3134 }
3135 /*
3136 default:
3137 {
3138 //all other entires ignored
3139 }
3140 */
3141 }
3142 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303143}
mpagenkodff5dda2020-08-28 11:52:01 +00003144
dbainbri4d3a0dc2020-12-02 00:33:42 +00003145func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003146 for _, action := range flow.GetActions(apFlowItem) {
3147 switch action.Type {
3148 /* not used:
3149 case of.OfpActionType_OFPAT_OUTPUT:
3150 {
mpagenko01e726e2020-10-23 09:45:29 +00003151 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003152 "Output": action.GetOutput()})
3153 }
3154 */
3155 case of.OfpActionType_OFPAT_PUSH_VLAN:
3156 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003157 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003158 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3159 }
3160 case of.OfpActionType_OFPAT_SET_FIELD:
3161 {
3162 pActionSetField := action.GetSetField()
3163 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003164 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003165 "OxcmClass": pActionSetField.Field.OxmClass})
3166 }
3167 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303168 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00003169 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303170 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003171 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303172 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00003173 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303174 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003175 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003176 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003177 "Type": pActionSetField.Field.GetOfbField().Type})
3178 }
3179 }
3180 /*
3181 default:
3182 {
3183 //all other entires ignored
3184 }
3185 */
3186 }
3187 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303188}
3189
3190//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
ozgecanetsia82b91a62021-05-21 18:54:49 +03003191func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort,
3192 apFlowMetaData *voltha.FlowMetadata) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05303193 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3194 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
3195 var loAddPcp, loSetPcp uint8
3196 var loIPProto uint32
3197 /* the TechProfileId is part of the flow Metadata - compare also comment within
3198 * OLT-Adapter:openolt_flowmgr.go
3199 * Metadata 8 bytes:
3200 * Most Significant 2 Bytes = Inner VLAN
3201 * Next 2 Bytes = Tech Profile ID(TPID)
3202 * Least Significant 4 Bytes = Port ID
3203 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3204 * subscriber related flows.
3205 */
3206
dbainbri4d3a0dc2020-12-02 00:33:42 +00003207 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303208 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003209 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05303210 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003211 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303212 }
mpagenko551a4d42020-12-08 18:09:20 +00003213 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003214 loCookie := apFlowItem.GetCookie()
3215 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00003216 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003217 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05303218
dbainbri4d3a0dc2020-12-02 00:33:42 +00003219 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003220 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303221 if loIPProto == 2 {
3222 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3223 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003224 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
3225 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303226 return nil
3227 }
mpagenko01e726e2020-10-23 09:45:29 +00003228 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003229 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003230
3231 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003232 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003233 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
3234 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3235 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3236 //TODO!!: Use DeviceId within the error response to rwCore
3237 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00003238 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003239 }
3240 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003241 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003242 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3243 } else {
3244 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3245 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3246 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303247 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003248 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003249 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003250 }
mpagenko9a304ea2020-12-16 15:54:01 +00003251
ozgecanetsia82b91a62021-05-21 18:54:49 +03003252 var meter *voltha.OfpMeterConfig
3253 if apFlowMetaData != nil {
3254 meter = apFlowMetaData.Meters[0]
3255 }
mpagenko2f487262021-08-23 15:59:06 +00003256 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3257 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3258 // when different rules are requested concurrently for the same uni
3259 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3260 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3261 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
3262 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 +05303263 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenko2f487262021-08-23 15:59:06 +00003264 //SetUniFlowParams() may block on some rule that is suspended-to-add
3265 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
mpagenkof1fc3862021-02-16 10:09:52 +00003266 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003267 loMatchVlan, loSetVlan, loSetPcp, false, meter)
mpagenko2f487262021-08-23 15:59:06 +00003268 dh.lockVlanConfig.RUnlock()
3269 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
mpagenkof1fc3862021-02-16 10:09:52 +00003270 return err
mpagenkodff5dda2020-08-28 11:52:01 +00003271 }
mpagenko2f487262021-08-23 15:59:06 +00003272 dh.lockVlanConfig.RUnlock()
3273 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko37047052021-07-27 10:01:29 +00003274 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003275 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false, meter)
mpagenko37047052021-07-27 10:01:29 +00003276 dh.lockVlanConfig.Unlock()
mpagenko2f487262021-08-23 15:59:06 +00003277 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
mpagenko37047052021-07-27 10:01:29 +00003278 return err
mpagenko01e726e2020-10-23 09:45:29 +00003279}
3280
3281//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00003282func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00003283 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3284 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3285 //no extra check is done on the rule parameters
3286 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3287 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3288 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3289 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003290 // - 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 +00003291 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003292 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003293
3294 /* TT related temporary workaround - should not be needed anymore
3295 for _, field := range flow.GetOfbFields(apFlowItem) {
3296 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3297 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00003298 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003299 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3300 if loIPProto == 2 {
3301 // 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 +00003302 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00003303 log.Fields{"device-id": dh.deviceID})
3304 return nil
3305 }
3306 }
3307 } //for all OfbFields
3308 */
3309
mpagenko9a304ea2020-12-16 15:54:01 +00003310 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003311 dh.lockVlanConfig.RLock()
3312 defer dh.lockVlanConfig.RUnlock()
mpagenko2f487262021-08-23 15:59:06 +00003313 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.deviceID, "uniID": apUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +00003314 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003315 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00003316 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003317 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00003318 log.Fields{"device-id": dh.deviceID})
3319 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003320 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00003321 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00003322
mpagenko01e726e2020-10-23 09:45:29 +00003323 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00003324}
3325
Himani Chawla26e555c2020-08-31 12:30:20 +05303326// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003327// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko37047052021-07-27 10:01:29 +00003328// precondition: dh.lockVlanConfig is locked by the caller!
mpagenko551a4d42020-12-08 18:09:20 +00003329func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003330 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
mpagenkodff5dda2020-08-28 11:52:01 +00003331 chVlanFilterFsm := make(chan Message, 2048)
3332
dbainbri4d3a0dc2020-12-02 00:33:42 +00003333 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003334 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003335 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303336 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003337 }
3338
dbainbri4d3a0dc2020-12-02 00:33:42 +00003339 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00003340 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003341 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter)
mpagenkodff5dda2020-08-28 11:52:01 +00003342 if pVlanFilterFsm != nil {
mpagenko37047052021-07-27 10:01:29 +00003343 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3344 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Himani Chawla26e555c2020-08-31 12:30:20 +05303345 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003346 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3347 if pVlanFilterStatemachine != nil {
3348 if pVlanFilterStatemachine.Is(vlanStDisabled) {
3349 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003350 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05303351 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003352 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303353 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003354 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05303355 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3356 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003357 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003358 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003359 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303360 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003361 }
3362 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003363 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003364 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303365 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003366 }
3367 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003368 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003369 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05303370 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003371 }
3372 return nil
3373}
3374
mpagenkofc4f56e2020-11-04 17:17:49 +00003375//VerifyVlanConfigRequest checks on existence of a given uniPort
3376// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003377func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003378 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
3379 var pCurrentUniPort *onuUniPort
3380 for _, uniPort := range dh.uniEntityMap {
3381 // only if this port is validated for operState transfer
3382 if uniPort.uniID == uint8(aUniID) {
3383 pCurrentUniPort = uniPort
3384 break //found - end search loop
3385 }
3386 }
3387 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003388 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00003389 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
3390 return
3391 }
mpagenko551a4d42020-12-08 18:09:20 +00003392 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003393}
3394
mpagenkodff5dda2020-08-28 11:52:01 +00003395//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00003396func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003397 //TODO!! verify and start pending flow configuration
3398 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3399 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003400
3401 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303402 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003403 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003404 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
3405 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3406 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003407 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandt72eaab72021-11-05 08:54:59 +00003408 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
mpagenko551a4d42020-12-08 18:09:20 +00003409 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
3410 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
3411 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3412 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3413 } else {
3414 /***** UniVlanConfigFsm continued */
3415 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
3416 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3417 "UniPort": apUniPort.portNo})
3418 }
3419 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
3420 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
3421 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3422 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3423 } else {
3424 /***** UniVlanConfigFsm continued */
3425 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3426 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3427 "UniPort": apUniPort.portNo})
3428 }
mpagenkodff5dda2020-08-28 11:52:01 +00003429 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003430 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3431 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003432 "UniPort": apUniPort.portNo})
3433 }
3434 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003435 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3436 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3437 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003438 }
3439 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003440 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003441 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003442 }
mpagenkof1fc3862021-02-16 10:09:52 +00003443 } else {
3444 dh.lockVlanConfig.RUnlock()
3445 }
mpagenkodff5dda2020-08-28 11:52:01 +00003446}
3447
3448//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3449// 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 +00003450func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3451 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003452 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3453 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003454 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303455 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003456 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003457}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003458
mpagenkof1fc3862021-02-16 10:09:52 +00003459//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3460func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3461 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3462 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3463 // obviously then parallel processing on the cancel must be avoided
3464 // deadline context to ensure completion of background routines waited for
3465 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3466 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3467 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3468
3469 aPDevEntry.resetKvProcessingErrorIndication()
3470 var wg sync.WaitGroup
3471 wg.Add(1) // for the 1 go routine to finish
3472
3473 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3474 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3475
3476 return aPDevEntry.getKvProcessingErrorIndication()
3477}
3478
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003479//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3480//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003481func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3482 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003483
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003484 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003485 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003486 return nil
3487 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003488 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003489
dbainbri4d3a0dc2020-12-02 00:33:42 +00003490 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003491 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003492 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003493 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3494 }
3495 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3496
mpagenkof1fc3862021-02-16 10:09:52 +00003497 if aWriteToKvStore {
3498 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3499 }
3500 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003501}
3502
dbainbri4d3a0dc2020-12-02 00:33:42 +00003503func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003504 defer cancel() //ensure termination of context (may be pro forma)
3505 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003506 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003507 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003508}
3509
dbainbri4d3a0dc2020-12-02 00:33:42 +00003510func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003511
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003512 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003513 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003514 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003515 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3516 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003517 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003518 return err
3519 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003520 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003521 return nil
3522 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003523 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003524 return nil
3525}
3526
dbainbri4d3a0dc2020-12-02 00:33:42 +00003527func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3528 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003529 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003530 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003531 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3532 }
mpagenkof1fc3862021-02-16 10:09:52 +00003533 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003534}
3535
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003536// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003537// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003538func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3539 dh.lockDevice.RLock()
3540 defer dh.lockDevice.RUnlock()
3541 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3542 return uniPort.entityID, nil
3543 }
3544 return 0, errors.New("error-fetching-uni-port")
3545}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003546
3547// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003548func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3549 var errorsList []error
3550 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 -08003551
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003552 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3553 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3554 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3555
3556 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3557 // successfully.
3558 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3559 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3560 if len(errorsList) > 0 {
3561 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3562 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003563 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003564 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3565 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003566}
3567
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003568func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3569 var err error
3570 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003571 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003572
3573 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3574 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3575 errorsList = append(errorsList, err)
3576 }
3577 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003578 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003579
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003580 return errorsList
3581}
3582
3583func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3584 var err error
3585 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003586 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003587 // Check if group metric related config is updated
3588 for _, v := range pmConfigs.Groups {
3589 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3590 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3591 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3592
3593 if ok && m.frequency != v.GroupFreq {
3594 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3595 errorsList = append(errorsList, err)
3596 }
3597 }
3598 if ok && m.enabled != v.Enabled {
3599 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3600 errorsList = append(errorsList, err)
3601 }
3602 }
3603 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003604 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003605 return errorsList
3606}
3607
3608func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3609 var err error
3610 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003611 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003612 // Check if standalone metric related config is updated
3613 for _, v := range pmConfigs.Metrics {
3614 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003615 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003616 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3617
3618 if ok && m.frequency != v.SampleFreq {
3619 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3620 errorsList = append(errorsList, err)
3621 }
3622 }
3623 if ok && m.enabled != v.Enabled {
3624 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3625 errorsList = append(errorsList, err)
3626 }
3627 }
3628 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003629 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003630 return errorsList
3631}
3632
3633// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003634func (dh *deviceHandler) startCollector(ctx context.Context) {
3635 logger.Debugf(ctx, "startingCollector")
3636
3637 // Start routine to process OMCI GET Responses
3638 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303639 // Create Extended Frame PM ME
3640 go dh.pOnuMetricsMgr.createEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003641 // Initialize the next metric collection time.
3642 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3643 // reset like onu rebooted.
3644 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003645 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003646 for {
3647 select {
3648 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003649 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003650 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003651 // Stop the L2 PM FSM
3652 go func() {
3653 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3654 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3655 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3656 }
3657 } else {
3658 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3659 }
3660 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003661 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3662 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3663 }
3664 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3665 dh.pOnuMetricsMgr.stopTicks <- true
3666 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003667
Girish Gowdrae09a6202021-01-12 18:10:59 -08003668 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003669 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3670 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3671 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3672 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3673 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003674 // Update the next metric collection time.
3675 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003676 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003677 } else {
3678 if dh.pmConfigs.Grouped { // metrics are managed as a group
3679 // parse through the group and standalone metrics to see it is time to collect their metrics
3680 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003681
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003682 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3683 // 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 -08003684 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3685 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003686 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3687 }
3688 }
3689 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3690 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3691 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3692 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3693 }
3694 }
3695 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3696
3697 // parse through the group and update the next metric collection time
3698 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3699 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3700 // 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 -08003701 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3702 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003703 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3704 }
3705 }
3706 // parse through the standalone metrics and update the next metric collection time
3707 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3708 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3709 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3710 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3711 }
3712 }
3713 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3714 } /* else { // metrics are not managed as a group
3715 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3716 } */
3717 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003718 }
3719 }
3720}
kesavandfdf77632021-01-26 23:40:33 -05003721
3722func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3723
3724 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3725 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3726}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003727
Himani Chawla43f95ff2021-06-03 00:24:12 +05303728func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3729 if dh.pOnuMetricsMgr == nil {
3730 return &extension.SingleGetValueResponse{
3731 Response: &extension.GetValueResponse{
3732 Status: extension.GetValueResponse_ERROR,
3733 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3734 },
3735 }
3736 }
3737 resp := dh.pOnuMetricsMgr.collectEthernetFrameExtendedPMCounters(ctx)
3738 return resp
3739}
3740
mpagenkof1fc3862021-02-16 10:09:52 +00003741func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3742 if pFsm == nil {
3743 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003744 }
mpagenkof1fc3862021-02-16 10:09:52 +00003745 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003746}
3747
mpagenkof1fc3862021-02-16 10:09:52 +00003748func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
mpagenko9c225032021-10-15 14:26:49 +00003749 var pAdapterFsm *AdapterFsm
3750 //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 +00003751 switch omciFsm {
3752 case cUploadFsm:
3753 {
mpagenko9c225032021-10-15 14:26:49 +00003754 if dh.pOnuOmciDevice != nil {
3755 pAdapterFsm = dh.pOnuOmciDevice.pMibUploadFsm
3756 } else {
3757 return true //FSM not active - so there is no activity on omci
3758 }
mpagenkof1fc3862021-02-16 10:09:52 +00003759 }
3760 case cDownloadFsm:
3761 {
mpagenko9c225032021-10-15 14:26:49 +00003762 if dh.pOnuOmciDevice != nil {
3763 pAdapterFsm = dh.pOnuOmciDevice.pMibDownloadFsm
3764 } else {
3765 return true //FSM not active - so there is no activity on omci
3766 }
mpagenkof1fc3862021-02-16 10:09:52 +00003767 }
3768 case cUniLockFsm:
3769 {
mpagenko9c225032021-10-15 14:26:49 +00003770 if dh.pLockStateFsm != nil {
3771 pAdapterFsm = dh.pLockStateFsm.pAdaptFsm
3772 } else {
3773 return true //FSM not active - so there is no activity on omci
3774 }
mpagenkof1fc3862021-02-16 10:09:52 +00003775 }
3776 case cUniUnLockFsm:
3777 {
mpagenko9c225032021-10-15 14:26:49 +00003778 if dh.pUnlockStateFsm != nil {
3779 pAdapterFsm = dh.pUnlockStateFsm.pAdaptFsm
3780 } else {
3781 return true //FSM not active - so there is no activity on omci
3782 }
mpagenkof1fc3862021-02-16 10:09:52 +00003783 }
3784 case cL2PmFsm:
3785 {
mpagenko9c225032021-10-15 14:26:49 +00003786 if dh.pOnuMetricsMgr != nil {
3787 pAdapterFsm = dh.pOnuMetricsMgr.pAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003788 } else {
3789 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003790 }
3791 }
mpagenko80622a52021-02-09 16:53:23 +00003792 case cOnuUpgradeFsm:
3793 {
3794 dh.lockUpgradeFsm.RLock()
3795 defer dh.lockUpgradeFsm.RUnlock()
mpagenko9c225032021-10-15 14:26:49 +00003796 if dh.pOnuUpradeFsm != nil {
3797 pAdapterFsm = dh.pOnuUpradeFsm.pAdaptFsm
3798 } else {
3799 return true //FSM not active - so there is no activity on omci
3800 }
mpagenko80622a52021-02-09 16:53:23 +00003801 }
mpagenkof1fc3862021-02-16 10:09:52 +00003802 default:
3803 {
3804 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3805 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3806 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003807 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003808 }
mpagenko9c225032021-10-15 14:26:49 +00003809 if pAdapterFsm != nil && pAdapterFsm.pFsm != nil {
3810 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.pFsm, wantedState)
3811 }
3812 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003813}
3814
mpagenkof1fc3862021-02-16 10:09:52 +00003815func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3816 for _, v := range dh.pOnuTP.pAniConfigFsm {
3817 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003818 return false
3819 }
3820 }
3821 return true
3822}
3823
mpagenkof1fc3862021-02-16 10:09:52 +00003824func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3825 dh.lockVlanConfig.RLock()
3826 defer dh.lockVlanConfig.RUnlock()
3827 for _, v := range dh.UniVlanConfigFsmMap {
3828 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3829 return false
3830 }
3831 }
3832 return true //FSM not active - so there is no activity on omci
3833}
3834
3835func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3836 dh.lockVlanConfig.RLock()
3837 defer dh.lockVlanConfig.RUnlock()
3838 for _, v := range dh.UniVlanConfigFsmMap {
3839 if v.pAdaptFsm.pFsm != nil {
3840 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3841 return true //there is at least one VLAN FSM with some active configuration
3842 }
3843 }
3844 }
3845 return false //there is no VLAN FSM with some active configuration
3846}
3847
3848func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3849 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3850 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3851 return false
3852 }
3853 }
3854 // a further check is done to identify, if at least some data traffic related configuration exists
3855 // 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])
3856 return dh.checkUserServiceExists(ctx)
3857}
3858
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003859func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3860 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3861 if err := dh.resetFsms(ctx, false); err != nil {
3862 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3863 // TODO: fatal error reset ONU, delete deviceHandler!
3864 return
3865 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003866 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003867 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003868}
3869
3870func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3871 dh.mutexCollectorFlag.Lock()
3872 dh.collectorIsRunning = flagValue
3873 dh.mutexCollectorFlag.Unlock()
3874}
3875
3876func (dh *deviceHandler) getCollectorIsRunning() bool {
3877 dh.mutexCollectorFlag.RLock()
3878 flagValue := dh.collectorIsRunning
3879 dh.mutexCollectorFlag.RUnlock()
3880 return flagValue
3881}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303882
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303883func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3884 dh.mutextAlarmManagerFlag.Lock()
3885 dh.alarmManagerIsRunning = flagValue
3886 dh.mutextAlarmManagerFlag.Unlock()
3887}
3888
Himani Chawla1472c682021-03-17 17:11:14 +05303889func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303890 dh.mutextAlarmManagerFlag.RLock()
3891 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303892 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303893 dh.mutextAlarmManagerFlag.RUnlock()
3894 return flagValue
3895}
3896
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303897func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3898 logger.Debugf(ctx, "startingAlarmManager")
3899
3900 // Start routine to process OMCI GET Responses
3901 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303902 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303903 if stop := <-dh.stopAlarmManager; stop {
3904 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303905 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303906 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303907 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3908 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3909 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303910 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303911 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303912 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3913 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303914 }
3915}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003916
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003917func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003918 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003919
Maninder7961d722021-06-16 22:10:28 +05303920 connectStatus := voltha.ConnectStatus_UNREACHABLE
3921 operState := voltha.OperStatus_UNKNOWN
3922
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003923 if !dh.isReconciling() {
3924 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003925 logger.Debugw(ctx, "wait for channel signal or timeout",
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00003926 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003927 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003928 case success := <-dh.chReconcilingFinished:
Holger Hildebrandt6be98372022-01-06 14:49:08 +00003929 logger.Debugw(ctx, "reconciling finished signal received",
3930 log.Fields{"device-id": dh.deviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
3931 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
3932 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
3933 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
3934 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
3935 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
3936 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
3937 // However, a later refactoring of the functionality remains unaffected.
3938 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003939 if success {
Maninderb5187552021-03-23 22:23:42 +05303940 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3941 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3942 log.Fields{"device-id": dh.deviceID})
3943 } else {
mpagenkob59fbed2021-11-23 16:55:20 +00003944 onuDevEntry.mutexPersOnuConfig.RLock()
Maninderb5187552021-03-23 22:23:42 +05303945 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3946 connectStatus = voltha.ConnectStatus_REACHABLE
3947 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3948 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3949 operState = voltha.OperStatus_ACTIVE
3950 } else {
3951 operState = voltha.OperStatus_ACTIVATING
3952 }
3953 }
3954 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3955 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3956 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3957 operState = voltha.OperStatus_DISCOVERED
3958 }
mpagenkob59fbed2021-11-23 16:55:20 +00003959 onuDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00003960 logger.Debugw(ctx, "Core DeviceStateUpdate",
3961 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303962 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003963 logger.Debugw(ctx, "reconciling has been finished in time",
3964 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303965 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, operState); err != nil {
3966 logger.Errorw(ctx, "unable to update device state to core",
3967 log.Fields{"device-id": dh.deviceID, "Err": err})
3968 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003969 } else {
Maninderb5187552021-03-23 22:23:42 +05303970 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003971 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303972
3973 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3974 logger.Errorw(ctx, "No valid OnuDevice",
3975 log.Fields{"device-id": dh.deviceID})
mpagenkob59fbed2021-11-23 16:55:20 +00003976 } else {
3977 onuDevEntry.mutexPersOnuConfig.RLock()
3978 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3979 connectStatus = voltha.ConnectStatus_REACHABLE
3980 }
3981 onuDevEntry.mutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05303982 }
3983
3984 dh.deviceReconcileFailedUpdate(ctx, drReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003985 }
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00003986 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003987 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3988 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt6be98372022-01-06 14:49:08 +00003989 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05303990
3991 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3992 logger.Errorw(ctx, "No valid OnuDevice",
3993 log.Fields{"device-id": dh.deviceID})
mpagenkob59fbed2021-11-23 16:55:20 +00003994 } else {
3995 onuDevEntry.mutexPersOnuConfig.RLock()
3996 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3997 connectStatus = voltha.ConnectStatus_REACHABLE
3998 }
3999 onuDevEntry.mutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304000 }
Maninder7961d722021-06-16 22:10:28 +05304001 dh.deviceReconcileFailedUpdate(ctx, drReconcileMaxTimeout, connectStatus)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004002 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004003 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004004 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00004005 dh.SetReconcilingReasonUpdate(false)
4006 dh.SetReconcilingFirstPass(true)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004007 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004008 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004009 dh.mutexReconcilingFlag.Lock()
4010 if skipOnuConfig {
4011 dh.reconciling = cSkipOnuConfigReconciling
4012 } else {
4013 dh.reconciling = cOnuConfigReconciling
4014 }
4015 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004016}
4017
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00004018func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
Girish Gowdra50e56422021-06-01 16:46:04 -07004019 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID, "success": success})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004020 if dh.isReconciling() {
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00004021 dh.sendChReconcileFinished(success)
4022 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4023 dh.SendChUniVlanConfigFinished(ctx, reconcileFlowResult)
4024 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004025 } else {
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00004026 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004027 }
4028}
4029
4030func (dh *deviceHandler) isReconciling() bool {
4031 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004032 defer dh.mutexReconcilingFlag.RUnlock()
4033 return dh.reconciling != cNoReconciling
4034}
4035
4036func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
4037 dh.mutexReconcilingFlag.RLock()
4038 defer dh.mutexReconcilingFlag.RUnlock()
4039 return dh.reconciling == cSkipOnuConfigReconciling
4040}
4041
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00004042func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4043 dh.mutexReconcilingFirstPassFlag.Lock()
4044 dh.reconcilingFirstPass = value
4045 dh.mutexReconcilingFirstPassFlag.Unlock()
4046}
4047
4048func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4049 dh.mutexReconcilingReasonUpdate.Lock()
4050 dh.reconcilingReasonUpdate = value
4051 dh.mutexReconcilingReasonUpdate.Unlock()
4052}
4053
4054func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4055 dh.mutexReconcilingReasonUpdate.RLock()
4056 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4057 return dh.reconcilingReasonUpdate
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004058}
4059
4060func (dh *deviceHandler) getDeviceReason() uint8 {
4061 dh.mutexDeviceReason.RLock()
4062 value := dh.deviceReason
4063 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004064 return value
4065}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004066
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00004067func (dh *deviceHandler) setDeviceReason(value uint8) {
4068 dh.mutexDeviceReason.Lock()
4069 dh.deviceReason = value
4070 dh.mutexDeviceReason.Unlock()
4071}
4072
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004073func (dh *deviceHandler) getDeviceReasonString() string {
4074 return deviceReasonMap[dh.getDeviceReason()]
4075}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004076
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004077func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
4078 dh.mutexReadyForOmciConfig.Lock()
4079 dh.readyForOmciConfig = flagValue
4080 dh.mutexReadyForOmciConfig.Unlock()
4081}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004082func (dh *deviceHandler) isReadyForOmciConfig() bool {
4083 dh.mutexReadyForOmciConfig.RLock()
4084 flagValue := dh.readyForOmciConfig
4085 dh.mutexReadyForOmciConfig.RUnlock()
4086 return flagValue
4087}
Maninder7961d722021-06-16 22:10:28 +05304088
4089func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
4090 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
4091 logger.Errorw(ctx, "unable to update device reason to core",
4092 log.Fields{"device-id": dh.deviceID, "Err": err})
4093 }
4094
4095 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
4096 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, voltha.OperStatus_RECONCILING_FAILED); err != nil {
4097 logger.Errorw(ctx, "unable to update device state to core",
4098 log.Fields{"device-id": dh.deviceID, "Err": err})
4099 }
4100}
Holger Hildebrandt72eaab72021-11-05 08:54:59 +00004101
4102// GetUniVlanConfigFsm - returns pointer to UniVlanConfigFsm
4103func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) *UniVlanConfigFsm {
4104 dh.lockVlanConfig.RLock()
4105 value := dh.UniVlanConfigFsmMap[uniID]
4106 dh.lockVlanConfig.RUnlock()
4107 return value
4108}
Holger Hildebrandtddc4fbd2022-02-04 14:10:36 +00004109
4110// PrepareForGarbageCollection - remove references to prepare for garbage collection
4111func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
4112 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
4113
4114 // Note: This function must be called as a goroutine to prevent blocking of further processing!
4115 // first let the objects rest for some time to give all asynchronously started
4116 // cleanup routines a chance to come to an end
Holger Hildebrandt39a95552022-04-25 13:14:34 +00004117 time.Sleep(2 * time.Second)
4118 if dh.pOnuOmciDevice != nil {
4119 if dh.pOnuOmciDevice.PDevOmciCC != nil {
4120 // Since we cannot rule out that one of the handlers had initiated any OMCI configurations during its
4121 // reset handling (even in future coding), request monitoring is canceled here one last time to
4122 // be sure that all corresponding go routines are terminated
4123 dh.pOnuOmciDevice.PDevOmciCC.CancelRequestMonitoring(ctx)
4124 }
4125 }
4126 time.Sleep(10 * time.Second)
Holger Hildebrandtddc4fbd2022-02-04 14:10:36 +00004127 if dh.pOnuTP != nil {
4128 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
4129 }
4130 if dh.pOnuMetricsMgr != nil {
4131 dh.pOnuMetricsMgr.PrepareForGarbageCollection(ctx, aDeviceID)
4132 }
4133 if dh.pAlarmMgr != nil {
4134 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
4135 }
4136 if dh.pSelfTestHdlr != nil {
4137 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
4138 }
4139 if dh.pLockStateFsm != nil {
4140 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4141 }
4142 if dh.pUnlockStateFsm != nil {
4143 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4144 }
4145 if dh.pOnuUpradeFsm != nil {
4146 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4147 }
4148 if dh.pOnuOmciDevice != nil {
4149 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
4150 }
4151 for k, v := range dh.UniVlanConfigFsmMap {
4152 v.PrepareForGarbageCollection(ctx, aDeviceID)
4153 delete(dh.UniVlanConfigFsmMap, k)
4154 }
4155 dh.pOnuOmciDevice = nil
4156 dh.pOnuTP = nil
4157 dh.pOnuMetricsMgr = nil
4158 dh.pAlarmMgr = nil
4159 dh.pSelfTestHdlr = nil
4160 dh.pLockStateFsm = nil
4161 dh.pUnlockStateFsm = nil
4162 dh.pOnuUpradeFsm = nil
4163}
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00004164
4165//WaitTimeout of waitGroupWithTimeOut is blocking
4166// returns true, if the wg request was executed successfully, false on timeout
4167func (wg *WaitGroupWithTimeOut) WaitTimeout(timeout time.Duration) bool {
4168 done := make(chan struct{})
4169 go func() {
4170 defer close(done)
4171 wg.Wait()
4172 }()
4173 select {
4174 case <-done:
4175 return true
4176 case <-time.After(timeout):
4177 return false
4178 }
4179}