blob: 2ef1926483643ab220d8bf6e03b828513e066f27 [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
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000017//Package core provides the utility for onu devices, flows and statistics
18package core
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000019
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
khenaidoo7d3c5582021-08-11 18:09:44 -040028 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/config"
mpagenko1f8e8822021-06-25 14:10:21 +000029
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000030 "github.com/gogo/protobuf/proto"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000031 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000032 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040033 "github.com/opencord/voltha-lib-go/v7/pkg/db"
34 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
35 flow "github.com/opencord/voltha-lib-go/v7/pkg/flows"
36 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
37 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Mahir Gunyelcb128ae2021-10-06 09:42:05 -070038 platform "github.com/opencord/voltha-lib-go/v7/pkg/platform"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000039 almgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/almgr"
40 avcfg "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/avcfg"
41 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
42 mib "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/mib"
43 otst "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/omcitst"
44 pmmgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/pmmgr"
45 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/swupg"
46 uniprt "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/uniprt"
khenaidoo7d3c5582021-08-11 18:09:44 -040047 vc "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo42dcdfd2021-10-19 17:34:12 -040048 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040049 "github.com/opencord/voltha-protos/v5/go/extension"
Holger Hildebrandt9afc1582021-11-30 16:10:19 +000050 "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo42dcdfd2021-10-19 17:34:12 -040051 ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040052 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
mpagenko59862f02021-10-11 08:53:18 +000053 "github.com/opencord/voltha-protos/v5/go/openolt"
khenaidoo7d3c5582021-08-11 18:09:44 -040054 oop "github.com/opencord/voltha-protos/v5/go/openolt"
mpagenko59862f02021-10-11 08:53:18 +000055 "github.com/opencord/voltha-protos/v5/go/tech_profile"
khenaidoo7d3c5582021-08-11 18:09:44 -040056 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000057)
58
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000059const (
mpagenko101ac942021-11-16 15:01:29 +000060 //constants for reconcile flow check channel
61 cWaitReconcileFlowAbortOnSuccess = 0xFFFD
62 cWaitReconcileFlowAbortOnError = 0xFFFE
63 cWaitReconcileFlowNoActivity = 0xFFFF
64)
65
66const (
67 // constants for timeouts
mpagenko38662d02021-08-11 09:45:19 +000068 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000069)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000070
mpagenko1cc3cb42020-07-27 15:24:38 +000071const (
mpagenko44bd8362021-11-15 11:40:05 +000072 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
73 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
74 // as long as such is not available by the libraries - use this workaround
75 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
76)
77
78const (
mpagenko1cc3cb42020-07-27 15:24:38 +000079 // events of Device FSM
80 devEvDeviceInit = "devEvDeviceInit"
81 devEvGrpcConnected = "devEvGrpcConnected"
82 devEvGrpcDisconnected = "devEvGrpcDisconnected"
83 devEvDeviceUpInd = "devEvDeviceUpInd"
84 devEvDeviceDownInd = "devEvDeviceDownInd"
85)
86const (
87 // states of Device FSM
88 devStNull = "devStNull"
89 devStDown = "devStDown"
90 devStInit = "devStInit"
91 devStConnected = "devStConnected"
92 devStUp = "devStUp"
93)
94
Holger Hildebrandt24d51952020-05-04 14:03:42 +000095//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
96const (
Himani Chawla4d908332020-08-31 12:30:20 +053097 pon = voltha.EventSubCategory_PON
98 //olt = voltha.EventSubCategory_OLT
99 //ont = voltha.EventSubCategory_ONT
100 //onu = voltha.EventSubCategory_ONU
101 //nni = voltha.EventSubCategory_NNI
102 //service = voltha.EventCategory_SERVICE
103 //security = voltha.EventCategory_SECURITY
104 equipment = voltha.EventCategory_EQUIPMENT
105 //processing = voltha.EventCategory_PROCESSING
106 //environment = voltha.EventCategory_ENVIRONMENT
107 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000108)
109
110const (
111 cEventObjectType = "ONU"
112)
113const (
114 cOnuActivatedEvent = "ONU_ACTIVATED"
115)
116
mpagenkof1fc3862021-02-16 10:09:52 +0000117type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000118 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000119 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000120}
121
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000122var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
123 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
124 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
125 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
126 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
127 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
128 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
129 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
130 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000131}
132
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000133const (
134 cNoReconciling = iota
135 cOnuConfigReconciling
136 cSkipOnuConfigReconciling
137)
138
Girish Gowdrae95687a2021-09-08 16:30:58 -0700139// FlowCb is the flow control block containing flow add/delete information along with a response channel
140type FlowCb struct {
141 ctx context.Context // Flow handler context
142 addFlow bool // if true flow to be added, else removed
143 flowItem *of.OfpFlowStats
144 uniPort *cmn.OnuUniPort
khenaidoo42dcdfd2021-10-19 17:34:12 -0400145 flowMetaData *of.FlowMetadata
Girish Gowdrae95687a2021-09-08 16:30:58 -0700146 respChan *chan error // channel to report the Flow handling error
147}
148
Himani Chawla6d2ae152020-09-02 13:11:20 +0530149//deviceHandler will interact with the ONU ? device.
150type deviceHandler struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000151 DeviceID string
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000152 DeviceType string
153 adminState string
154 device *voltha.Device
155 logicalDeviceID string
156 ProxyAddressID string
157 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530158 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000159 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000160
khenaidoo7d3c5582021-08-11 18:09:44 -0400161 coreClient *vgrpc.Client
162 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000163
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800164 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400165 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800166
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000167 pOpenOnuAc *OpenONUAC
168 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530169 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000170 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000171 pOnuOmciDevice *mib.OnuDeviceEntry
172 pOnuTP *avcfg.OnuUniTechProf
173 pOnuMetricsMgr *pmmgr.OnuMetricsManager
174 pAlarmMgr *almgr.OnuAlarmManager
175 pSelfTestHdlr *otst.SelfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000176 exitChannel chan int
177 lockDevice sync.RWMutex
178 pOnuIndication *oop.OnuIndication
179 deviceReason uint8
180 mutexDeviceReason sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000181 pLockStateFsm *uniprt.LockStateFsm
182 pUnlockStateFsm *uniprt.LockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000183
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000184 //flowMgr *OpenOltFlowMgr
185 //eventMgr *OpenOltEventMgr
186 //resourceMgr *rsrcMgr.OpenOltResourceMgr
187
188 //discOnus sync.Map
189 //onus sync.Map
190 //portStats *OpenOltStatisticsMgr
mpagenko101ac942021-11-16 15:01:29 +0000191 collectorIsRunning bool
192 mutexCollectorFlag sync.RWMutex
193 stopCollector chan bool
194 alarmManagerIsRunning bool
195 mutextAlarmManagerFlag sync.RWMutex
196 stopAlarmManager chan bool
197 stopHeartbeatCheck chan bool
198 uniEntityMap cmn.OnuUniPortMap
199 mutexKvStoreContext sync.Mutex
200 lockVlanConfig sync.RWMutex
201 lockVlanAdd sync.RWMutex
202 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
203 lockUpgradeFsm sync.RWMutex
204 pOnuUpradeFsm *swupg.OnuUpgradeFsm
205 upgradeCanceled bool
206 reconciling uint8
207 mutexReconcilingFlag sync.RWMutex
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000208 reconcilingReasonUpdate bool
209 mutexReconcilingReasonUpdate sync.RWMutex
mpagenko101ac942021-11-16 15:01:29 +0000210 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
211 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
212 reconcileExpiryComplete time.Duration
213 reconcileExpiryVlanConfig time.Duration
214 mutexReadyForOmciConfig sync.RWMutex
215 readyForOmciConfig bool
216 deletionInProgress bool
217 mutexDeletionInProgressFlag sync.RWMutex
218 pLastUpgradeImageState *voltha.ImageState
219 upgradeFsmChan chan struct{}
Girish Gowdrae95687a2021-09-08 16:30:58 -0700220
221 flowCbChan []chan FlowCb
222 mutexFlowMonitoringRoutineFlag sync.RWMutex
223 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
224 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000225}
226
Himani Chawla6d2ae152020-09-02 13:11:20 +0530227//newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400228func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530229 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400230 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000231 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400232 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000233 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000234 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000235 dh.DeviceType = cloned.Type
236 dh.adminState = "up"
237 dh.device = cloned
238 dh.pOpenOnuAc = adapter
239 dh.exitChannel = make(chan int, 1)
240 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000241 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000242 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000243 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530244 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530245 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000246 dh.stopHeartbeatCheck = make(chan bool, 2)
247 //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 +0000248 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000249 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000250 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000251 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000252 dh.lockUpgradeFsm = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000253 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000254 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000255 dh.reconcilingReasonUpdate = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000256 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000257 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
258 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
259 if rECSeconds < 2 {
260 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
261 rECSeconds = 2
262 }
263 rEVCSeconds := rECSeconds / 2
264 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000265 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000266 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000267 dh.pLastUpgradeImageState = &voltha.ImageState{
268 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
269 Reason: voltha.ImageState_UNKNOWN_ERROR,
270 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
271 }
272 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000273
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800274 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
275 dh.pmConfigs = cloned.PmConfigs
276 } /* else {
277 // will be populated when onu_metrics_mananger is initialized.
278 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800279
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000280 // Device related state machine
281 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000282 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000283 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000284 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
285 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
286 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
287 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
288 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000289 },
290 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000291 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
292 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
293 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
294 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
295 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
296 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
297 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
298 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000299 },
300 )
mpagenkoaf801632020-07-03 10:00:42 +0000301
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000302 return &dh
303}
304
Himani Chawla6d2ae152020-09-02 13:11:20 +0530305// start save the device to the data model
306func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000307 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000308 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000309 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000310}
311
Himani Chawla4d908332020-08-31 12:30:20 +0530312/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000313// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530314func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000315 logger.Debug("stopping-device-handler")
316 dh.exitChannel <- 1
317}
Himani Chawla4d908332020-08-31 12:30:20 +0530318*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000319
320// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530321// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000322
Girish Gowdrae0140f02021-02-02 16:55:09 -0800323//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530324func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400325 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000326
dbainbri4d3a0dc2020-12-02 00:33:42 +0000327 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000328 if dh.pDeviceStateFsm.Is(devStNull) {
329 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000330 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000331 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000332 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800333 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
334 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800335 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400336 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000337 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800338 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800339 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000340 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000341 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000342 }
343
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000344}
345
khenaidoo42dcdfd2021-10-19 17:34:12 -0400346func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000347 /* 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 +0530348 //assuming omci message content is hex coded!
349 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000350 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000351 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000352 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000353 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530354 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000355 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000356 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000357 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400358 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530359 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000360 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
361 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530362}
363
khenaidoo42dcdfd2021-10-19 17:34:12 -0400364func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000365 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000366
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000367 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000368 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000369 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
370 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000371 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530372 if dh.pOnuTP == nil {
373 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000374 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000375 log.Fields{"device-id": dh.DeviceID})
376 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530377 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000378 if !dh.IsReadyForOmciConfig() {
379 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
380 "device-state": dh.GetDeviceReasonString()})
381 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530382 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000383 //previous state test here was just this one, now extended for more states to reject the SetRequest:
384 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
385 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530386
Himani Chawla26e555c2020-08-31 12:30:20 +0530387 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000388 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
389 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000390 dh.pOnuTP.LockTpProcMutex()
391 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000392
mpagenko44bd8362021-11-15 11:40:05 +0000393 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000394 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000395 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000396 }
397 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000398 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800399 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700400 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800401 return err
402 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700403 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000404
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000405 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530406
Girish Gowdra50e56422021-06-01 16:46:04 -0700407 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400408 case *ia.TechProfileDownloadMessage_TpInstance:
Girish Gowdra50e56422021-06-01 16:46:04 -0700409 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
410 // if there has been some change for some uni TechProfilePath
411 //in order to allow concurrent calls to other dh instances we do not wait for execution here
412 //but doing so we can not indicate problems to the caller (who does what with that then?)
413 //by now we just assume straightforward successful execution
414 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
415 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530416
Girish Gowdra50e56422021-06-01 16:46:04 -0700417 // deadline context to ensure completion of background routines waited for
418 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
419 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
420 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000421
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000422 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700423
424 var wg sync.WaitGroup
425 wg.Add(1) // for the 1 go routine to finish
426 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000427 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700428 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000429 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
430 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.DeviceID, "err": tpErr, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700431 return tpErr
432 }
433 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
434 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000435 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700436 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000437 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700438 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000439 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
440 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.DeviceID, "err": kvErr, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700441 return kvErr
442 }
443 return nil
444 default:
445 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"tp-path": techProfMsg.TpInstancePath})
446 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700447 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530448 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000449 // no change, nothing really to do - return success
Girish Gowdra50e56422021-06-01 16:46:04 -0700450 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 +0530451 return nil
452}
453
khenaidoo42dcdfd2021-10-19 17:34:12 -0400454func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000455 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530456
457 if dh.pOnuTP == nil {
458 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000459 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000460 log.Fields{"device-id": dh.DeviceID})
461 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530462 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530463 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000464 dh.pOnuTP.LockTpProcMutex()
465 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530466
mpagenko0f543222021-11-03 16:24:14 +0000467 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
468 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
469 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000470 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000471 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000472 }
473 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000474 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800475 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000476 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
477 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800478 return err
479 }
mpagenko0f543222021-11-03 16:24:14 +0000480 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
481 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000482 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000483
Mahir Gunyel9545be22021-07-04 15:53:16 -0700484 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000485 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000486
Himani Chawla26e555c2020-08-31 12:30:20 +0530487}
488
khenaidoo42dcdfd2021-10-19 17:34:12 -0400489func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000490 logger.Infow(ctx, "delete-tcont-request start", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000491
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000492 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000493 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000494 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
495 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000496 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530497 if dh.pOnuTP == nil {
498 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000499 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000500 log.Fields{"device-id": dh.DeviceID})
501 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530502 }
503
Himani Chawla26e555c2020-08-31 12:30:20 +0530504 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000505 dh.pOnuTP.LockTpProcMutex()
506 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000507
mpagenko0f543222021-11-03 16:24:14 +0000508 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
509 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
510 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000511 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000512 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000513 }
514 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700515 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000516 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800517 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000518 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
519 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800520 return err
521 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000522 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 +0000523
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000524 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530525
Mahir Gunyel9545be22021-07-04 15:53:16 -0700526 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000527 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000528
Mahir Gunyel9545be22021-07-04 15:53:16 -0700529}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000530
Mahir Gunyel9545be22021-07-04 15:53:16 -0700531func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000532 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
533 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700534 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000535 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
536 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530537 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700538 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000539 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700540 resourceName = "Gem"
541 } else {
542 resourceName = "Tcont"
543 }
544
545 // deadline context to ensure completion of background routines waited for
546 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
547 dctx, cancel := context.WithDeadline(context.Background(), deadline)
548
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000549 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700550
551 var wg sync.WaitGroup
552 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000553 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700554 resource, entryID, &wg)
555 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000556 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
557 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700558 return err
559 }
560
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000561 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
562 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
563 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
564 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700565 var wg2 sync.WaitGroup
566 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
567 wg2.Add(1)
568 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000569 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
570 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700571 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000572 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
573 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700574 return err
575 }
576 }
577 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000578 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700579 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530580 return nil
581}
582
mpagenkodff5dda2020-08-28 11:52:01 +0000583//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000584func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400585 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400586 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700587 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
588 var errorsList []error
589 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000590 //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 +0000591 if apOfFlowChanges.ToRemove != nil {
592 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000593 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000594 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000595 "device-id": dh.DeviceID})
596 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700597 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000598 continue
599 }
600 flowInPort := flow.GetInPort(flowItem)
601 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000602 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
603 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700604 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000605 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000606 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000607 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000608 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000609 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000610 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000611 continue
612 } else {
613 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000614 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000615 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
616 loUniPort = uniPort
617 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000618 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000619 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000620 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000621 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700622 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000623 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000624 }
625 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000626 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000627 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
628 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700629
630 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
631 // Step1 : Fill flowControlBlock
632 // Step2 : Push the flowControlBlock to ONU channel
633 // Step3 : Wait on response channel for response
634 // Step4 : Return error value
635 startTime := time.Now()
636 respChan := make(chan error)
637 flowCb := FlowCb{
638 ctx: ctx,
639 addFlow: false,
640 flowItem: flowItem,
641 flowMetaData: nil,
642 uniPort: loUniPort,
643 respChan: &respChan,
644 }
645 dh.flowCbChan[loUniPort.UniID] <- flowCb
646 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
647 // Wait on the channel for flow handlers return value
648 retError = <-respChan
649 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
650 if retError != nil {
651 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
652 log.Fields{"device-id": dh.DeviceID, "error": retError})
653 errorsList = append(errorsList, retError)
654 continue
655 }
656 } else {
657 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
658 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000659 }
660 }
661 }
662 }
mpagenko01e726e2020-10-23 09:45:29 +0000663 if apOfFlowChanges.ToAdd != nil {
664 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
665 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000666 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000667 "device-id": dh.DeviceID})
668 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700669 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000670 continue
671 }
672 flowInPort := flow.GetInPort(flowItem)
673 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000674 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
675 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700676 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000677 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000678 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000679 } else if flowInPort == dh.ponPortNumber {
680 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000681 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000682 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000683 continue
684 } else {
685 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000686 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000687 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
688 loUniPort = uniPort
689 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000690 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000691 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000692 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000693 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700694 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000695 continue
mpagenko01e726e2020-10-23 09:45:29 +0000696 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000697 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
698 // if not, we just throw some error here to have an indication about that, if we really need to support that
699 // then we would need to create some means to activate the internal stored flows
700 // after the device gets active automatically (and still with its dependency to the TechProfile)
701 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
702 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000703 if !dh.IsReadyForOmciConfig() {
704 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
705 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700706 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
707 errorsList = append(errorsList, retError)
708 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000709 }
710
mpagenko01e726e2020-10-23 09:45:29 +0000711 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000712 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000713 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
714 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700715 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
716 // Step1 : Fill flowControlBlock
717 // Step2 : Push the flowControlBlock to ONU channel
718 // Step3 : Wait on response channel for response
719 // Step4 : Return error value
720 startTime := time.Now()
721 respChan := make(chan error)
722 flowCb := FlowCb{
723 ctx: ctx,
724 addFlow: true,
725 flowItem: flowItem,
726 flowMetaData: apFlowMetaData,
727 uniPort: loUniPort,
728 respChan: &respChan,
729 }
730 dh.flowCbChan[loUniPort.UniID] <- flowCb
731 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
732 // Wait on the channel for flow handlers return value
733 retError = <-respChan
734 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
735 if retError != nil {
736 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
737 log.Fields{"device-id": dh.DeviceID, "error": retError})
738 errorsList = append(errorsList, retError)
739 continue
740 }
741 } else {
742 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
743 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000744 }
745 }
746 }
747 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700748 if len(errorsList) > 0 {
749 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
750 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
751 }
752 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000753}
754
Himani Chawla6d2ae152020-09-02 13:11:20 +0530755//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000756//following are the expected device states after this activity:
757//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
758// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000759func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
760 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000761
mpagenko900ee4b2020-10-12 11:56:34 +0000762 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000763 //note that disableDevice sequences in some 'ONU active' state may yield also
764 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000765 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000766 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000767 //disable-device shall be just a UNi/ONU-G related admin state setting
768 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000769
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000770 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000771 // disable UNI ports/ONU
772 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
773 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000774 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000775 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000776 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000777 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000778 }
779 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000780 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000781 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000782 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400783 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000784 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000785 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400786 OperStatus: voltha.OperStatus_UNKNOWN,
787 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000788 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000789 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000790 }
mpagenko01e726e2020-10-23 09:45:29 +0000791 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000792
793 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000794 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000795 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300796 }
797}
798
Himani Chawla6d2ae152020-09-02 13:11:20 +0530799//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000800func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
801 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000802
mpagenkoaa3afe92021-05-21 16:20:58 +0000803 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000804 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
805 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
806 // for real ONU's that should have nearly no influence
807 // Note that for real ONU's there is anyway a problematic situation with following sequence:
808 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
809 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
810 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000811 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000812
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000813 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000814 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000815 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000816 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000817 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000818 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000819 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000820 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300821}
822
dbainbri4d3a0dc2020-12-02 00:33:42 +0000823func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000824 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000825
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000826 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000827 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000828 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000829 return
830 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000831 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000832 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000833 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000834 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000835 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000836 }
mpagenko101ac942021-11-16 15:01:29 +0000837 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000838 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000839 }
Himani Chawla4d908332020-08-31 12:30:20 +0530840 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000841 pDevEntry.MutexPersOnuConfig.RLock()
842 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
843 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
844 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
845 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
846 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000847 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000848}
849
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000850func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000851 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000852
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000853 continueWithFlowConfig := false
854
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000855 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000856 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000857 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000858 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
859 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000860 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000861 dh.pOnuTP.LockTpProcMutex()
862 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000863
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000864 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000865 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000866 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
867 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000868 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000869 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000870 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
871 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000872 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000873 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700874 techProfsFound := false
875 techProfInstLoadFailed := false
876outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000877 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000878 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000879 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000880 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000881 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000882 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000883 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000884 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000885 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
886 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000887 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000888 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000889 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700890 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000891 var iaTechTpInst ia.TechProfileDownloadMessage
892 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800893 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000894 pDevEntry.MutexReconciledTpInstances.RLock()
895 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
896 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000897 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000898 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700899 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000900 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700901 break outerLoop
902 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000903 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000904 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700905 var tpInst tech_profile.TechProfileInstance
906 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400907 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700908 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000909 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000910 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700911 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000912 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000913 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700914 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
915 break outerLoop
916 }
917
Girish Gowdra041dcb32020-11-16 16:54:30 -0800918 // deadline context to ensure completion of background routines waited for
919 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
920 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000921 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000922
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000923 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800924 var wg sync.WaitGroup
925 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000926 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000927 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000928 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
929 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700930 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
931 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800932 }
mpagenko2dc896e2021-08-02 12:03:59 +0000933 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000934 if len(uniData.PersFlowParams) != 0 {
935 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000936 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000937 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000938 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000939 } // for all UNI entries from SOnuPersistentData
940 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
941 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000942 }
mpagenko2dc896e2021-08-02 12:03:59 +0000943
944 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
945 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000946
947 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +0000948}
949
950func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
951 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
952 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000953 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000954 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000955 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000956 return
957 }
mpagenko2dc896e2021-08-02 12:03:59 +0000958 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000959 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +0000960 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -0700961 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000962 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000963 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000964 }
mpagenko2dc896e2021-08-02 12:03:59 +0000965 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000966 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000967 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000968 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000969 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000970}
971
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000972func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
973 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000974
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000975 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000976 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000977 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000978 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000979 return
980 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000981
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000982 pDevEntry.MutexPersOnuConfig.RLock()
983 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
984 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000985 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000986 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000987 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000988 return
989 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000990 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +0000991 var uniVlanConfigEntries []uint8
992 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
993
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000994 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000995 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
996 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000997 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000998 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000999 continue
1000 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001001 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001002 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001003 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001004 // It doesn't make sense to configure any flows if no TPs are available
1005 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001006 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001007 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1008 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001009 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001010 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001011
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001012 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001013 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001014 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001015 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001016 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1017 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001018 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001019 return
1020 }
mpagenko101ac942021-11-16 15:01:29 +00001021 //needed to split up function due to sca complexity
1022 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1023
mpagenko2dc896e2021-08-02 12:03:59 +00001024 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001025 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001026 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1027 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001028 // this can't be used as global finished reconciling flag because
1029 // assumes is getting called before the state machines for the last flow is completed,
1030 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001031 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1032 } // for all UNI entries from SOnuPersistentData
1033 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001034
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001035 if !flowsFound {
1036 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001037 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001038 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001039 return
1040 }
mpagenko101ac942021-11-16 15:01:29 +00001041
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001042 if dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00001043 //only with 'SkipOnuConfig' we need to wait for all finished-signals
1044 // from vlanConfig processing of all UNI's.
1045 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1046 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1047 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1048 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1049 log.Fields{"device-id": dh.DeviceID})
1050 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1051 if pDevEntry != nil {
1052 pDevEntry.SendChReconcilingFlowsFinished(true)
1053 }
1054 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001055 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
mpagenko101ac942021-11-16 15:01:29 +00001056 log.Fields{"device-id": dh.DeviceID})
1057 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1058 if pDevEntry != nil {
1059 pDevEntry.SendChReconcilingFlowsFinished(false)
1060 }
1061 return
1062 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001063 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001064 }
1065}
1066
mpagenko101ac942021-11-16 15:01:29 +00001067func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1068 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1069 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1070 flowsProcessed := 0
1071 lastFlowToReconcile := false
1072 loUniID := apUniPort.UniID
1073 for _, flowData := range aPersFlowParam {
1074 if dh.IsSkipOnuConfigReconciling() {
1075 if !(*apFlowsFound) {
1076 *apFlowsFound = true
1077 syncChannel := make(chan struct{})
1078 // start go routine with select() on reconciling vlan config channel before
1079 // starting vlan config reconciling process to prevent loss of any signal
1080 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1081 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1082 //block until the wait routine is really blocked on channel input
1083 // in order to prevent to early ready signal from VlanConfig processing
1084 <-syncChannel
1085 }
1086 if flowsProcessed == len(aPersFlowParam)-1 {
1087 var uniAdded bool
1088 lastFlowToReconcile = true
1089 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1090 apWaitGroup.Add(1) //increment the waiting group
1091 }
1092 }
1093 }
1094 // note for above block: also lastFlowToReconcile (as parameter to flow config below)
1095 // is only relevant in the vlanConfig processing for IsSkipOnuConfigReconciling = true
1096 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1097 "device-id": dh.DeviceID, "uni-id": loUniID,
1098 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1099 dh.lockVlanConfig.Lock()
1100 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1101 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1102 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
1103 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1104 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter, nil); err != nil {
1105 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1106 }
1107 } else {
1108 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
1109 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1110 uint8(flowData.VlanRuleParams.SetPcp), cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
1111 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1112 }
1113 }
1114 dh.lockVlanConfig.Unlock()
1115 flowsProcessed++
1116 } //for all flows of this UNI
1117}
1118
1119//waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1120// and decrements the according handler wait group waiting for these indications
1121func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1122 waitGroup *cmn.WaitGroupWithTimeOut) {
1123 var reconciledUniVlanConfigEntries []uint8
1124 var appended bool
1125 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1126 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1127 "device-id": dh.DeviceID, "expiry": expiry})
1128 // indicate blocking on channel now to the caller
1129 aSyncChannel <- struct{}{}
1130 for {
1131 select {
1132 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1133 switch uniIndication {
1134 // no activity requested (should normally not be received) - just continue waiting
1135 case cWaitReconcileFlowNoActivity:
1136 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1137 case cWaitReconcileFlowAbortOnError:
1138 logger.Debugw(ctx, "waitReconcileFlow aborted on error",
1139 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1140 return
1141 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1142 case cWaitReconcileFlowAbortOnSuccess:
1143 logger.Debugw(ctx, "waitReconcileFlow aborted on success",
1144 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1145 return
1146 // this should be a valid UNI vlan config done indication
1147 default:
1148 if uniIndication < platform.MaxUnisPerOnu {
1149 logger.Debugw(ctx, "reconciling flows has been finished in time for this UNI",
1150 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1151 if reconciledUniVlanConfigEntries, appended =
1152 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1153 waitGroup.Done()
1154 }
1155 } else {
1156 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored",
1157 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1158 }
1159 } //switch uniIndication
1160
1161 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1162 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1163 log.Fields{"device-id": dh.DeviceID})
1164 return
1165 }
1166 }
1167}
1168
1169func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1170 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1171}
1172
1173func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1174 for _, ele := range slice {
1175 if ele == val {
1176 return slice, false
1177 }
1178 }
1179 return append(slice, val), true
1180}
1181
1182// sendChReconcileFinished - sends true or false on reconcileFinish channel
1183func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1184 if dh != nil { //if the object still exists (might have been already deleted in background)
1185 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1186 select {
1187 case dh.chReconcilingFinished <- success:
1188 default:
1189 }
1190 }
1191}
1192
1193// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1194func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1195 if dh != nil { //if the object still exists (might have been already deleted in background)
1196 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1197 select {
1198 case dh.chUniVlanConfigReconcilingDone <- value:
1199 default:
1200 }
1201 }
1202}
1203
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001204func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001205 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001206 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001207}
1208
dbainbri4d3a0dc2020-12-02 00:33:42 +00001209func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001210 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001211
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001212 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001213 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001214 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001215 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001216 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001217 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001218
1219 // deadline context to ensure completion of background routines waited for
1220 //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 +05301221 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001222 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001223
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001224 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001225
1226 var wg sync.WaitGroup
1227 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001228 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001229 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001230
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001231 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001232 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001233}
1234
mpagenko15ff4a52021-03-02 10:09:20 +00001235//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1236// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001237// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001238//was and is called in background - error return does not make sense
1239func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001240 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001241 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001242 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001243 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001244 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001245 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301246 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001247 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001248 return
Himani Chawla4d908332020-08-31 12:30:20 +05301249 }
mpagenko01e726e2020-10-23 09:45:29 +00001250
1251 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001252 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001253
mpagenko44bd8362021-11-15 11:40:05 +00001254 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001255 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001256 // do not set the ConnStatus here as it may conflict with the parallel setting from ONU down indication (updateInterface())
khenaidoo42dcdfd2021-10-19 17:34:12 -04001257 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001258 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001259 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001260 OperStatus: voltha.OperStatus_DISCOVERED,
1261 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001262 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001263 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001264 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001265 }
mpagenkoe4782082021-11-25 12:04:26 +00001266 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001267 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001268 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001269 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001270 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1271 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1272 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1273 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001274}
1275
mpagenkoc8bba412021-01-15 15:38:44 +00001276//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001277// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001278func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001279 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001280 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001281 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001282
1283 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001284 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001285 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001286 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1287 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001288 }
1289
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001290 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001291 var inactiveImageID uint16
1292 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1293 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001294 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1295 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001296 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001297 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001298 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001299 if err == nil {
1300 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1301 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001302 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001303 }
1304 } else {
1305 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001306 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001307 }
mpagenko15ff4a52021-03-02 10:09:20 +00001308 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001309 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001310 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001311 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1312 dh.upgradeCanceled = true
1313 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1314 }
mpagenko38662d02021-08-11 09:45:19 +00001315 //no effort spent anymore for the old API to automatically cancel and restart the download
1316 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001317 }
mpagenko15ff4a52021-03-02 10:09:20 +00001318 } else {
1319 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001320 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001321 }
1322 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001323 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1324 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001325 }
1326 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001327}
1328
mpagenkoc26d4c02021-05-06 14:27:57 +00001329//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1330// after the OnuImage has been downloaded to the adapter, called in background
1331func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001332 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001333
1334 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001335 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001336 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001337 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001338 return
1339 }
1340
1341 var inactiveImageID uint16
1342 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1343 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001344 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001345
mpagenko59862f02021-10-11 08:53:18 +00001346 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001347 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001348 // but must be still locked at calling createOnuUpgradeFsm
1349 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1350 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1351 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001352 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1353 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001354 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001355 //flush the remove upgradeFsmChan channel
1356 select {
1357 case <-dh.upgradeFsmChan:
1358 logger.Debug(ctx, "flushed-upgrade-fsm-channel")
1359 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001360 }
mpagenko59862f02021-10-11 08:53:18 +00001361 dh.lockUpgradeFsm.Unlock()
1362 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1363 dh.upgradeCanceled = true
1364 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1365 }
mpagenko38662d02021-08-11 09:45:19 +00001366 select {
1367 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001368 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001369 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1370 return
1371 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001372 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001373 }
mpagenko59862f02021-10-11 08:53:18 +00001374 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001375 }
mpagenko38662d02021-08-11 09:45:19 +00001376
1377 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001378 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001379 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001380 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001381 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001382 if err == nil {
1383 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1384 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1385 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001386 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001387 return
1388 }
mpagenko38662d02021-08-11 09:45:19 +00001389 } else {
1390 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001391 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001392 }
1393 return
1394 }
1395 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001396 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001397}
1398
1399//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001400func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1401 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001402 var err error
1403 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1404 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1405 // 2.) activation of the inactive image
1406
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001407 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001408 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001409 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1410 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001411 }
1412 dh.lockUpgradeFsm.RLock()
1413 if dh.pOnuUpradeFsm != nil {
1414 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001415 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001416 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001417 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1418 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001419 }
mpagenko59862f02021-10-11 08:53:18 +00001420 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1421 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1422 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1423 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001424 // use the OnuVendor identification from this device for the internal unique name
1425 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001426 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001427 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001428 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001429 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001430 "device-id": dh.DeviceID, "error": err})
1431 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001432 }
mpagenko183647c2021-06-08 15:25:04 +00001433 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001434 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001435 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001436 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001437 } //else
1438 dh.lockUpgradeFsm.RUnlock()
1439
1440 // 2.) check if requested image-version equals the inactive one and start its activation
1441 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1442 var inactiveImageID uint16
1443 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1444 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001445 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1446 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001447 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001448 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001449 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001450 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001451 if err == nil {
1452 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1453 inactiveImageID, aCommitRequest); err != nil {
1454 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001455 "device-id": dh.DeviceID, "error": err})
1456 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001457 }
1458 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001459 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001460 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001461 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001462 } //else
1463 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001464 "device-id": dh.DeviceID, "error": err})
1465 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001466}
1467
1468//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001469func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1470 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001471 var err error
1472 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1473 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1474 // 2.) commitment of the active image
1475
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001476 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001477 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001478 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1479 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001480 }
1481 dh.lockUpgradeFsm.RLock()
1482 if dh.pOnuUpradeFsm != nil {
1483 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001484 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001485 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001486 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1487 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001488 }
mpagenko59862f02021-10-11 08:53:18 +00001489 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1490 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1491 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1492 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001493 // use the OnuVendor identification from this device for the internal unique name
1494 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001495 // 1.) check a started upgrade process and relay the commitment request to it
1496 // the running upgrade may be based either on the imageIdentifier (started from download)
1497 // or on the imageVersion (started from pure activation)
1498 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1499 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001500 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001501 "device-id": dh.DeviceID, "error": err})
1502 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001503 }
mpagenko183647c2021-06-08 15:25:04 +00001504 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001505 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001506 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001507 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001508 } //else
1509 dh.lockUpgradeFsm.RUnlock()
1510
mpagenko183647c2021-06-08 15:25:04 +00001511 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001512 var activeImageID uint16
1513 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1514 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001515 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1516 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001517 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001518 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001519 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001520 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001521 if err == nil {
1522 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1523 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001524 "device-id": dh.DeviceID, "error": err})
1525 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001526 }
1527 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001528 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001529 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001530 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001531 } //else
1532 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001533 "device-id": dh.DeviceID, "error": err})
1534 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001535}
1536
mpagenkoaa3afe92021-05-21 16:20:58 +00001537func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001538 aVersion string) *voltha.ImageState {
1539 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001540 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001541 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001542 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001543 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1544 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1545 if aVersion == dh.pLastUpgradeImageState.Version {
1546 pImageState = dh.pLastUpgradeImageState
1547 } else { //state request for an image version different from last processed image version
1548 pImageState = &voltha.ImageState{
1549 Version: aVersion,
1550 //we cannot state something concerning this version
1551 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1552 Reason: voltha.ImageState_NO_ERROR,
1553 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1554 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001555 }
1556 }
mpagenko38662d02021-08-11 09:45:19 +00001557 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001558}
1559
1560func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1561 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001562 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001563 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001564 dh.lockUpgradeFsm.RLock()
1565 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001566 dh.lockUpgradeFsm.RUnlock()
1567 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001568 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001569 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1570 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1571 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1572 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1573 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1574 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001575 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1576 dh.upgradeCanceled = true
1577 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1578 }
mpagenko45586762021-10-01 08:30:22 +00001579 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001580 } else {
mpagenko45586762021-10-01 08:30:22 +00001581 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001582 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1583 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1584 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1585 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1586 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1587 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001588 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1589 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001590 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1591 //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 +00001592 }
1593}
1594
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001595func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1596
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001597 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001598
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001599 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001600 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001601 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1602 pDevEntry.MutexOnuImageStatus.Lock()
1603 pDevEntry.POnuImageStatus = onuImageStatus
1604 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001605
1606 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001607 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001608 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1609 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001610 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1611 pDevEntry.MutexOnuImageStatus.Lock()
1612 pDevEntry.POnuImageStatus = nil
1613 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001614 return images, err
1615}
1616
Himani Chawla6d2ae152020-09-02 13:11:20 +05301617// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001618// #####################################################################################
1619
1620// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301621// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001622
dbainbri4d3a0dc2020-12-02 00:33:42 +00001623func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001624 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 +00001625}
1626
1627// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001628func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001629
dbainbri4d3a0dc2020-12-02 00:33:42 +00001630 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001631 var err error
1632
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001633 // populate what we know. rest comes later after mib sync
1634 dh.device.Root = false
1635 dh.device.Vendor = "OpenONU"
1636 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001637 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001638 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001639
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001640 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001641
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001642 if !dh.IsReconciling() {
1643 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001644 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1645 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1646 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301647 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001648 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001649 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001650 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001651 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001652
Himani Chawla4d908332020-08-31 12:30:20 +05301653 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001654 dh.ponPortNumber = dh.device.ParentPortNo
1655
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001656 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1657 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1658 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001659 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001660 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301661 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001662
1663 /*
1664 self._pon = PonPort.create(self, self._pon_port_number)
1665 self._pon.add_peer(self.parent_id, self._pon_port_number)
1666 self.logger.debug('adding-pon-port-to-agent',
1667 type=self._pon.get_port().type,
1668 admin_state=self._pon.get_port().admin_state,
1669 oper_status=self._pon.get_port().oper_status,
1670 )
1671 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001672 if !dh.IsReconciling() {
1673 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001674 var ponPortNo uint32 = 1
1675 if dh.ponPortNumber != 0 {
1676 ponPortNo = dh.ponPortNumber
1677 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001678
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001679 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001680 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001681 PortNo: ponPortNo,
1682 Label: fmt.Sprintf("pon-%d", ponPortNo),
1683 Type: voltha.Port_PON_ONU,
1684 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301685 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001686 PortNo: ponPortNo}}, // Peer port is parent's port number
1687 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001688 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001689 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001690 e.Cancel(err)
1691 return
1692 }
1693 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001694 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001695 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001696 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001697}
1698
1699// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001700func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001701
dbainbri4d3a0dc2020-12-02 00:33:42 +00001702 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001703 var err error
1704 /*
1705 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1706 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1707 return nil
1708 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001709 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1710 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001711 e.Cancel(err)
1712 return
1713 }
1714
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001715 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001716 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001717 // reconcilement will be continued after mib download is done
1718 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001719
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001720 /*
1721 ############################################################################
1722 # Setup Alarm handler
1723 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1724 device.serial_number)
1725 ############################################################################
1726 # Setup PM configuration for this device
1727 # Pass in ONU specific options
1728 kwargs = {
1729 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1730 'heartbeat': self.heartbeat,
1731 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1732 }
1733 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1734 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1735 self.logical_device_id, device.serial_number,
1736 grouped=True, freq_override=False, **kwargs)
1737 pm_config = self._pm_metrics.make_proto()
1738 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1739 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1740 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1741
1742 # Note, ONU ID and UNI intf set in add_uni_port method
1743 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1744 ani_ports=[self._pon])
1745
1746 # Code to Run OMCI Test Action
1747 kwargs_omci_test_action = {
1748 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1749 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1750 }
1751 serial_number = device.serial_number
1752 self._test_request = OmciTestRequest(self.core_proxy,
1753 self.omci_agent, self.device_id,
1754 AniG, serial_number,
1755 self.logical_device_id,
1756 exclusive=False,
1757 **kwargs_omci_test_action)
1758
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001759 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001760 else:
1761 self.logger.info('onu-already-activated')
1762 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001763
dbainbri4d3a0dc2020-12-02 00:33:42 +00001764 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001765}
1766
1767// doStateConnected get the device info and update to voltha core
1768// for comparison of the original method (not that easy to uncomment): compare here:
1769// voltha-openolt-adapter/adaptercore/device_handler.go
1770// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001771func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001772
dbainbri4d3a0dc2020-12-02 00:33:42 +00001773 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301774 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001775 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001776 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001777}
1778
1779// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001780func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001781
dbainbri4d3a0dc2020-12-02 00:33:42 +00001782 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301783 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001784 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001785 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001786
1787 /*
1788 // Synchronous call to update device state - this method is run in its own go routine
1789 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1790 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001791 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 +00001792 return err
1793 }
1794 return nil
1795 */
1796}
1797
1798// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001799func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001800
dbainbri4d3a0dc2020-12-02 00:33:42 +00001801 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001802 var err error
1803
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001804 device := dh.device
1805 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001806 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001807 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001808 e.Cancel(err)
1809 return
1810 }
1811
1812 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001813 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001814 /*
1815 // Update the all ports state on that device to disable
1816 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001817 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001818 return er
1819 }
1820
1821 //Update the device oper state and connection status
1822 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1823 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1824 dh.device = cloned
1825
1826 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001827 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001828 return er
1829 }
1830
1831 //get the child device for the parent device
1832 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1833 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001834 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001835 return err
1836 }
1837 for _, onuDevice := range onuDevices.Items {
1838
1839 // Update onu state as down in onu adapter
1840 onuInd := oop.OnuIndication{}
1841 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001842 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001843 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1844 if er != nil {
1845 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001846 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001847 //Do not return here and continue to process other ONUs
1848 }
1849 }
1850 // * Discovered ONUs entries need to be cleared , since after OLT
1851 // is up, it starts sending discovery indications again* /
1852 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001853 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001854 return nil
1855 */
Himani Chawla4d908332020-08-31 12:30:20 +05301856 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001857 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001858 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001859}
1860
Himani Chawla6d2ae152020-09-02 13:11:20 +05301861// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001862// #################################################################################
1863
1864// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301865// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001866
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001867//GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
1868func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001869 dh.lockDevice.RLock()
1870 pOnuDeviceEntry := dh.pOnuOmciDevice
1871 if aWait && pOnuDeviceEntry == nil {
1872 //keep the read sema short to allow for subsequent write
1873 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001874 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001875 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1876 // so it might be needed to wait here for that event with some timeout
1877 select {
1878 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001879 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001880 return nil
1881 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001882 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001883 // if written now, we can return the written value without sema
1884 return dh.pOnuOmciDevice
1885 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001886 }
mpagenko3af1f032020-06-10 08:53:41 +00001887 dh.lockDevice.RUnlock()
1888 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001889}
1890
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001891//setDeviceHandlerEntries sets the ONU device entry within the handler
1892func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1893 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001894 dh.lockDevice.Lock()
1895 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001896 dh.pOnuOmciDevice = apDeviceEntry
1897 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001898 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301899 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001900 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001901}
1902
Himani Chawla6d2ae152020-09-02 13:11:20 +05301903//addOnuDeviceEntry creates a new ONU device or returns the existing
1904func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001905 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001906
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001907 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001908 if deviceEntry == nil {
1909 /* costum_me_map in python code seems always to be None,
1910 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1911 /* also no 'clock' argument - usage open ...*/
1912 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001913 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1914 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1915 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1916 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1917 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001918 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001919 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001920 // fire deviceEntry ready event to spread to possibly waiting processing
1921 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001922 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001923 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001924 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001925 }
1926 // might be updated with some error handling !!!
1927 return nil
1928}
1929
dbainbri4d3a0dc2020-12-02 00:33:42 +00001930func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1931 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001932 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1933
1934 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001935
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001936 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001937 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001938 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1939 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001940 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001941 if !dh.IsReconciling() {
1942 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001944 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001945 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001946 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001947 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001948
khenaidoo42dcdfd2021-10-19 17:34:12 -04001949 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001950 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001951 OperStatus: voltha.OperStatus_ACTIVATING,
1952 ConnStatus: voltha.ConnectStatus_REACHABLE,
1953 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001954 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001955 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001956 }
1957 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001958 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001959 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001960
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001961 pDevEntry.MutexPersOnuConfig.RLock()
1962 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1963 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001964 logger.Debugw(ctx, "reconciling - uni-ports were not unlocked before adapter restart - resume with a normal start-up",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001965 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001966 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001967 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001968 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001969 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001970 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001971 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1972 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1973 // in python code it looks as the started onu_omci_device might have been updated with some new instance state of the core device
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001974 // but I would not know why, and the go code anyway does not work with the device directly anymore in the mib.OnuDeviceEntry
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001975 // so let's just try to keep it simple ...
1976 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001977 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001978 if err != nil || device == nil {
1979 //TODO: needs to handle error scenarios
1980 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1981 return errors.New("Voltha Device not found")
1982 }
1983 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001984
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001985 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001986 return err
mpagenko3af1f032020-06-10 08:53:41 +00001987 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001988 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001989
1990 /* this might be a good time for Omci Verify message? */
1991 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001992 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001993 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001994 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001995 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001996
1997 /* give the handler some time here to wait for the OMCi verification result
1998 after Timeout start and try MibUpload FSM anyway
1999 (to prevent stopping on just not supported OMCI verification from ONU) */
2000 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002001 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00002002 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002003 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00002004 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002005 }
2006
2007 /* In py code it looks earlier (on activate ..)
2008 # Code to Run OMCI Test Action
2009 kwargs_omci_test_action = {
2010 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2011 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2012 }
2013 serial_number = device.serial_number
2014 self._test_request = OmciTestRequest(self.core_proxy,
2015 self.omci_agent, self.device_id,
2016 AniG, serial_number,
2017 self.logical_device_id,
2018 exclusive=False,
2019 **kwargs_omci_test_action)
2020 ...
2021 # Start test requests after a brief pause
2022 if not self._test_request_started:
2023 self._test_request_started = True
2024 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2025 reactor.callLater(tststart, self._test_request.start_collector)
2026
2027 */
2028 /* which is then: in omci_test_request.py : */
2029 /*
2030 def start_collector(self, callback=None):
2031 """
2032 Start the collection loop for an adapter if the frequency > 0
2033
2034 :param callback: (callable) Function to call to collect PM data
2035 """
2036 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2037 if callback is None:
2038 callback = self.perform_test_omci
2039
2040 if self.lc is None:
2041 self.lc = LoopingCall(callback)
2042
2043 if self.default_freq > 0:
2044 self.lc.start(interval=self.default_freq / 10)
2045
2046 def perform_test_omci(self):
2047 """
2048 Perform the initial test request
2049 """
2050 ani_g_entities = self._device.configuration.ani_g_entities
2051 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2052 is not None else None
2053 self._entity_id = ani_g_entities_ids[0]
2054 self.logger.info('perform-test', entity_class=self._entity_class,
2055 entity_id=self._entity_id)
2056 try:
2057 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2058 result = yield self._device.omci_cc.send(frame)
2059 if not result.fields['omci_message'].fields['success_code']:
2060 self.logger.info('Self-Test Submitted Successfully',
2061 code=result.fields[
2062 'omci_message'].fields['success_code'])
2063 else:
2064 raise TestFailure('Test Failure: {}'.format(
2065 result.fields['omci_message'].fields['success_code']))
2066 except TimeoutError as e:
2067 self.deferred.errback(failure.Failure(e))
2068
2069 except Exception as e:
2070 self.logger.exception('perform-test-Error', e=e,
2071 class_id=self._entity_class,
2072 entity_id=self._entity_id)
2073 self.deferred.errback(failure.Failure(e))
2074
2075 */
2076
2077 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002078 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002079
mpagenko1cc3cb42020-07-27 15:24:38 +00002080 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2081 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2082 * 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 +05302083 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002084 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002085 //call MibUploadFSM - transition up to state UlStInSync
2086 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002087 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002088 if pMibUlFsm.Is(mib.UlStDisabled) {
2089 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2090 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2091 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302092 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002093 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302094 //Determine ONU status and start/re-start MIB Synchronization tasks
2095 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002096 if pDevEntry.IsNewOnu() {
2097 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2098 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2099 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002100 }
Himani Chawla4d908332020-08-31 12:30:20 +05302101 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002102 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2103 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2104 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302105 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002106 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002107 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002108 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002109 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002110 "device-id": dh.DeviceID})
2111 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002112 }
2113 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002114 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2115 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002116 }
2117 return nil
2118}
2119
dbainbri4d3a0dc2020-12-02 00:33:42 +00002120func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00002121 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002122 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002123 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
2124 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002125
mpagenko900ee4b2020-10-12 11:56:34 +00002126 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2127 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2128 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002129 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002130 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002131 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002132 // abort: system behavior is just unstable ...
2133 return err
2134 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002135 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002136 _ = 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 +00002137
2138 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002139 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002140 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002141 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002142 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2143 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002144 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002145 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002146
2147 //TODO!!! remove existing traffic profiles
2148 /* from py code, if TP's exist, remove them - not yet implemented
2149 self._tp = dict()
2150 # Let TP download happen again
2151 for uni_id in self._tp_service_specific_task:
2152 self._tp_service_specific_task[uni_id].clear()
2153 for uni_id in self._tech_profile_download_done:
2154 self._tech_profile_download_done[uni_id].clear()
2155 */
2156
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002157 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002158
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002159 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002160
mpagenkoe4782082021-11-25 12:04:26 +00002161 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002162 // abort: system behavior is just unstable ...
2163 return err
2164 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002165 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002166 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002167 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002168 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002169 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2170 OperStatus: voltha.OperStatus_DISCOVERED,
2171 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002172 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002173 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002174 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002175 // abort: system behavior is just unstable ...
2176 return err
2177 }
2178 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002179 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002180 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002181 return nil
2182}
2183
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002184func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002185 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2186 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2187 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2188 // and using the stop/reset event should never harm
2189
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002190 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002191 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002192 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2193 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00002194 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002195 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002196 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002197 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002198 pDevEntry.MutexOnuImageStatus.RLock()
2199 if pDevEntry.POnuImageStatus != nil {
2200 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002201 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002202 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002203
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002204 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002205 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002206 }
2207 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002208 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002209 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002210 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002211 }
mpagenko101ac942021-11-16 15:01:29 +00002212 //stop any deviceHandler reconcile processing (if running)
2213 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002214 //port lock/unlock FSM's may be active
2215 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002216 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002217 }
2218 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002219 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002220 }
2221 //techProfile related PonAniConfigFsm FSM may be active
2222 if dh.pOnuTP != nil {
2223 // should always be the case here
2224 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002225 if dh.pOnuTP.PAniConfigFsm != nil {
2226 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2227 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002228 }
mpagenko900ee4b2020-10-12 11:56:34 +00002229 }
2230 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002231 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002232 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002233 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002234 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002235 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002236 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002237 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002238 } else {
2239 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002240 }
2241 }
2242 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002243 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002244 // Stop collector routine
2245 dh.stopCollector <- true
2246 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002247 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302248 dh.stopAlarmManager <- true
2249 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002250 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002251 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002252 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302253
Girish Gowdrae95687a2021-09-08 16:30:58 -07002254 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2255
mpagenko80622a52021-02-09 16:53:23 +00002256 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002257 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002258 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002259 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002260 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002261 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002262 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002263 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2264 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2265 // (even though it may also run into direct cancellation, a bit hard to verify here)
2266 // so don't set 'dh.upgradeCanceled = true' here!
2267 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2268 }
mpagenko38662d02021-08-11 09:45:19 +00002269 }
mpagenko80622a52021-02-09 16:53:23 +00002270
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002271 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002272 return nil
2273}
2274
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002275func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2276 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 +05302277
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002278 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002279 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002280 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002281 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002282 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002283 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002284 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002285
mpagenkoa40e99a2020-11-17 13:50:39 +00002286 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2287 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2288 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2289 * disable/enable toggling here to allow traffic
2290 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2291 * like the py comment says:
2292 * # start by locking all the unis till mib sync and initial mib is downloaded
2293 * # this way we can capture the port down/up events when we are ready
2294 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302295
mpagenkoa40e99a2020-11-17 13:50:39 +00002296 // Init Uni Ports to Admin locked state
2297 // *** should generate UniLockStateDone event *****
2298 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002299 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002300 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002301 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002302 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002303 }
2304}
2305
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002306func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2307 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302308 /* Mib download procedure -
2309 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2310 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002311 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002312 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002313 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002314 return
2315 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002316 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302317 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002318 if pMibDlFsm.Is(mib.DlStDisabled) {
2319 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2320 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 +05302321 // maybe try a FSM reset and then again ... - TODO!!!
2322 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002323 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302324 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002325 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2326 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302327 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002328 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302329 //Begin MIB data download (running autonomously)
2330 }
2331 }
2332 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002333 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002334 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302335 // maybe try a FSM reset and then again ... - TODO!!!
2336 }
2337 /***** Mib download started */
2338 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002339 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302340 }
2341}
2342
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002343func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2344 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302345 //initiate DevStateUpdate
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002346 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002347 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002348 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002349 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2350 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2351 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2352 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002353 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002354 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002355 ConnStatus: voltha.ConnectStatus_REACHABLE,
2356 OperStatus: voltha.OperStatus_ACTIVE,
2357 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302358 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002359 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302360 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002361 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302362 }
2363 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002364 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002365 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302366 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002367 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002368
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002369 if !dh.GetCollectorIsRunning() {
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002370 // Start PM collector routine
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002371 go dh.StartCollector(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002372 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002373 if !dh.GetAlarmManagerIsRunning(ctx) {
2374 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002375 }
2376
Girish Gowdrae95687a2021-09-08 16:30:58 -07002377 // Start flow handler routines per UNI
2378 for _, uniPort := range dh.uniEntityMap {
2379 // only if this port was enabled for use by the operator at startup
2380 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2381 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2382 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2383 }
2384 }
2385 }
2386
Girish Gowdrae0140f02021-02-02 16:55:09 -08002387 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002388 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002389 // There is no way we should be landing here, but if we do then
2390 // there is nothing much we can do about this other than log error
2391 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2392 }
2393
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002394 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002395
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002396 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002397 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002398 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002399 return
2400 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002401 pDevEntry.MutexPersOnuConfig.RLock()
2402 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2403 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002404 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002405 log.Fields{"device-id": dh.DeviceID})
2406 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002407 // reconcilement will be continued after ani config is done
2408 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002409 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002410 // *** should generate UniUnlockStateDone event *****
2411 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002412 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002413 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002414 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002415 dh.runUniLockFsm(ctx, false)
2416 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302417 }
2418}
2419
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002420func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2421 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302422
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002423 if !dh.IsReconciling() {
2424 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002425 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002426 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2427 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002428 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002429 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002430 return
2431 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002432 pDevEntry.MutexPersOnuConfig.Lock()
2433 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2434 pDevEntry.MutexPersOnuConfig.Unlock()
2435 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002436 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002437 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002438 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302439 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002440 logger.Debugw(ctx, "reconciling - don't notify core that onu went to active but trigger tech profile config",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002441 log.Fields{"device-id": dh.DeviceID})
2442 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002443 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302444 }
2445}
2446
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002447func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002448 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002449 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002450
mpagenko44bd8362021-11-15 11:40:05 +00002451 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002452 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002453 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002454 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002455 OperStatus: voltha.OperStatus_UNKNOWN,
2456 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002457 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002458 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002459 }
2460
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002461 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002462 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002463 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002464
2465 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002466 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002467
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002468 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002469 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002470 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002471 return
2472 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002473 pDevEntry.MutexPersOnuConfig.Lock()
2474 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2475 pDevEntry.MutexPersOnuConfig.Unlock()
2476 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002477 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002478 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002479 }
mpagenko900ee4b2020-10-12 11:56:34 +00002480}
2481
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002482func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002483 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002484 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002485 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002486 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002487 ConnStatus: voltha.ConnectStatus_REACHABLE,
2488 OperStatus: voltha.OperStatus_ACTIVE,
2489 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002490 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002491 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002492 }
2493
dbainbri4d3a0dc2020-12-02 00:33:42 +00002494 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002495 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002496 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002497 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002498
2499 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002500 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002501
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002502 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002503 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002504 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002505 return
2506 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002507 pDevEntry.MutexPersOnuConfig.Lock()
2508 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2509 pDevEntry.MutexPersOnuConfig.Unlock()
2510 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002511 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002512 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002513 }
mpagenko900ee4b2020-10-12 11:56:34 +00002514}
2515
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002516func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2517 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2518 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002519 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002520 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002521 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002522 OperStatus: voltha.OperStatus_FAILED,
2523 }); err != nil {
2524 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2525 }
2526}
2527
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002528func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2529 if devEvent == cmn.OmciAniConfigDone {
2530 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002531 // attention: the device reason update is done based on ONU-UNI-Port related activity
2532 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002533 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002534 // which may be the case from some previous activity even on this UNI Port (but also other UNI ports)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002535 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302536 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002537 if dh.IsReconciling() {
2538 go dh.ReconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002539 }
2540 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002541 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002542 // attention: the device reason update is done based on ONU-UNI-Port related activity
2543 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002544 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002545 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
2546 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002547 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002548 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302549}
2550
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002551func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002552 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002553 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302554 // attention: the device reason update is done based on ONU-UNI-Port related activity
2555 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302556
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002557 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2558 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00002559 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00002560 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002561 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002562 if dh.IsReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002563 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002564 }
2565 }
2566 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002567 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002568 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00002569 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002570 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302571 }
mpagenkof1fc3862021-02-16 10:09:52 +00002572
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002573 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002574 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002575 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002576 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002577 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002578 }
2579 } else {
2580 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002581 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002582 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302583}
2584
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002585//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
2586func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302587 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002588 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002589 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002590 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002591 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002592 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002593 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002594 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002595 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002596 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002597 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002598 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002599 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002600 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002601 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002602 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002603 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002604 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002605 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002606 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002607 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002608 case cmn.UniEnableStateFailed:
2609 {
2610 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2611 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002612 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002613 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002614 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002615 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002616 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002617 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002618 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002619 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002620 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002621 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002622 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002623 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002624 default:
2625 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002626 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002627 }
2628 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002629}
2630
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002631func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002632 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002633 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302634 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002635 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002636 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002637 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302638 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002639 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002640 if pUniPort == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002641 logger.Warnw(ctx, "OnuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002642 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002643 //store UniPort with the System-PortNumber key
2644 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002645 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002646 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002647 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
2648 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002649 } //error logging already within UniPort method
2650 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002651 logger.Debugw(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002652 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002653 }
2654 }
2655}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002656
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002657func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2658 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002659 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002660 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002661 return
2662 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002663 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002664 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002665 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2666 for _, mgmtEntityID := range pptpInstKeys {
2667 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002668 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002669 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2670 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002671 }
2672 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002673 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002674 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002675 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002676 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2677 for _, mgmtEntityID := range veipInstKeys {
2678 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002679 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002680 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2681 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002682 }
2683 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002684 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002685 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002686 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002687 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2688 for _, mgmtEntityID := range potsInstKeys {
2689 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002690 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002691 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2692 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002693 }
2694 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002695 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002696 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002697 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002698 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002699 return
2700 }
2701
mpagenko2c3f6c52021-11-23 11:22:10 +00002702 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
2703 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
2704 // also for the POTS ports, so we include them already for future usage - should anyway do no great harm
Girish Gowdrae95687a2021-09-08 16:30:58 -07002705 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2706 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2707 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00002708 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
2709 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002710 for i := 0; i < int(uniCnt); i++ {
2711 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
2712 dh.stopFlowMonitoringRoutine[i] = make(chan bool)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002713 }
2714}
2715
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002716// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2717func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002718 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302719 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002720 // with following remark:
2721 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2722 // # load on the core
2723
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002724 // 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 +00002725
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002726 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002727 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002728 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2729 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2730 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2731 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002732 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002733 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002734 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002735 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002736 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002737 PortNo: port.PortNo,
2738 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002739 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002740 logger.Errorw(ctx, "port-state-update-failed", log.Fields{"error": err, "port-no": uniPort.PortNo, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002741 }
2742 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002743 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002744 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002745 }
mpagenko3af1f032020-06-10 08:53:41 +00002746 }
2747 }
2748}
2749
2750// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002751func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2752 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002753 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2754 for uniNo, uniPort := range dh.uniEntityMap {
2755 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002756
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002757 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2758 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2759 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2760 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002761 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002762 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002763 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002764 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002765 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002766 PortNo: port.PortNo,
2767 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002768 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002769 logger.Errorw(ctx, "port-state-update-failed", log.Fields{"error": err, "port-no": uniPort.PortNo, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002770 }
2771 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002772 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002773 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002774 }
2775
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002776 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002777 }
2778}
2779
2780// ONU_Active/Inactive announcement on system KAFKA bus
2781// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002782func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002783 var de voltha.DeviceEvent
2784 eventContext := make(map[string]string)
2785 //Populating event context
2786 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002787 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002788 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002789 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302790 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002791 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 +00002792 }
2793 oltSerialNumber := parentDevice.SerialNumber
2794
2795 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2796 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2797 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302798 eventContext["olt-serial-number"] = oltSerialNumber
2799 eventContext["device-id"] = aDeviceID
2800 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002801 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002802 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2803 deviceEntry.MutexPersOnuConfig.RLock()
2804 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2805 deviceEntry.MutexPersOnuConfig.RUnlock()
2806 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
2807 deviceEntry.MutexPersOnuConfig.RLock()
2808 eventContext["vendor"] = deviceEntry.SOnuPersistentData.PersVendorID
2809 deviceEntry.MutexPersOnuConfig.RUnlock()
2810 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002811 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2812 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2813 } else {
2814 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2815 log.Fields{"device-id": aDeviceID})
2816 return
2817 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002818
2819 /* Populating device event body */
2820 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302821 de.ResourceId = aDeviceID
2822 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002823 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2824 de.Description = fmt.Sprintf("%s Event - %s - %s",
2825 cEventObjectType, cOnuActivatedEvent, "Raised")
2826 } else {
2827 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2828 de.Description = fmt.Sprintf("%s Event - %s - %s",
2829 cEventObjectType, cOnuActivatedEvent, "Cleared")
2830 }
2831 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002832 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2833 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302834 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002835 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002836 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302837 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002838}
2839
Himani Chawla4d908332020-08-31 12:30:20 +05302840// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002841func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2842 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002843 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302844 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002845 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002846 sFsmName = "LockStateFSM"
2847 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002848 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002849 sFsmName = "UnLockStateFSM"
2850 }
mpagenko3af1f032020-06-10 08:53:41 +00002851
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002852 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002853 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002854 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002855 return
2856 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002857 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002858 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302859 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002860 dh.pLockStateFsm = pLSFsm
2861 } else {
2862 dh.pUnlockStateFsm = pLSFsm
2863 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002864 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002865 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002866 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002867 }
2868}
2869
2870// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002871func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002872 /* Uni Port lock/unlock procedure -
2873 ***** should run via 'adminDone' state and generate the argument requested event *****
2874 */
2875 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302876 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002877 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002878 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2879 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002880 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2881 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002882 }
2883 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002884 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002885 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2886 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002887 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2888 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002889 }
2890 }
2891 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002892 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2893 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002894 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002895 // maybe try a FSM reset and then again ... - TODO!!!
2896 } else {
2897 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002898 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002899 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002900 }
2901 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002902 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002903 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002904 // maybe try a FSM reset and then again ... - TODO!!!
2905 }
2906 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002907 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002908 // maybe try a FSM reset and then again ... - TODO!!!
2909 }
2910}
2911
mpagenko80622a52021-02-09 16:53:23 +00002912// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00002913// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002914func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002915 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002916 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002917 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002918 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002919 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002920 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002921 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002922 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002923 sFsmName, chUpgradeFsm)
2924 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002925 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00002926 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002927 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
2928 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
mpagenko80622a52021-02-09 16:53:23 +00002929 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2930 // maybe try a FSM reset and then again ... - TODO!!!
2931 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2932 }
mpagenko59862f02021-10-11 08:53:18 +00002933 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00002934 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2935 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00002936 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2937 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002938 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002939 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002940 } else {
2941 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002942 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002943 // maybe try a FSM reset and then again ... - TODO!!!
2944 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2945 }
2946 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002947 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002948 // maybe try a FSM reset and then again ... - TODO!!!
2949 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2950 }
2951 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002952 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002953 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2954 }
2955 return nil
2956}
2957
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002958// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
2959func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002960 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002961 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002962 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00002963 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2964 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00002965 dh.pLastUpgradeImageState = apImageState
2966 dh.lockUpgradeFsm.Unlock()
2967 //signal upgradeFsm removed using non-blocking channel send
2968 select {
2969 case dh.upgradeFsmChan <- struct{}{}:
2970 default:
2971 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002972 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00002973 }
mpagenko80622a52021-02-09 16:53:23 +00002974}
2975
mpagenko15ff4a52021-03-02 10:09:20 +00002976// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2977func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002978 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00002979 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002980 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002981 return
2982 }
2983
2984 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00002985 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00002986 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002987 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
2988 dh.lockUpgradeFsm.RUnlock()
2989 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
2990 return
2991 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002992 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00002993 if pUpgradeStatemachine != nil {
2994 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2995 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002996 UpgradeState := pUpgradeStatemachine.Current()
2997 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
2998 (UpgradeState == swupg.UpgradeStRequestingActivate) {
2999 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003000 // here no need to update the upgrade image state to activated as the state will be immediately be set to committing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003001 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003002 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3003 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003004 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003005 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003006 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003007 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3008 dh.upgradeCanceled = true
3009 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3010 }
mpagenko15ff4a52021-03-02 10:09:20 +00003011 return
3012 }
mpagenko59862f02021-10-11 08:53:18 +00003013 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003014 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3015 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003016 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003017 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
mpagenko1f8e8822021-06-25 14:10:21 +00003018 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
3019 return
3020 }
3021 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003022 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003023 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003024 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3025 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
mpagenko1f8e8822021-06-25 14:10:21 +00003026 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
3027 return
3028 }
3029 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003030 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003031 }
3032 } else {
3033 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit/on ActivateResponse, but load did not start with expected image Id",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003034 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003035 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3036 dh.upgradeCanceled = true
3037 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3038 }
mpagenko1f8e8822021-06-25 14:10:21 +00003039 }
mpagenko15ff4a52021-03-02 10:09:20 +00003040 return
3041 }
mpagenko59862f02021-10-11 08:53:18 +00003042 dh.lockUpgradeFsm.RUnlock()
3043 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3044 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003045 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3046 dh.upgradeCanceled = true
3047 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3048 }
mpagenko59862f02021-10-11 08:53:18 +00003049 return
3050 }
3051 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3052 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3053 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3054 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3055 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3056 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3057 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003058 }
mpagenko15ff4a52021-03-02 10:09:20 +00003059 }
3060 }
3061 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003062 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003063 }
mpagenko59862f02021-10-11 08:53:18 +00003064 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003065}
3066
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003067//SetBackend provides a DB backend for the specified path on the existing KV client
3068func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003069
3070 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003071 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003072 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003073 kvbackend := &db.Backend{
3074 Client: dh.pOpenOnuAc.kvClient,
3075 StoreType: dh.pOpenOnuAc.KVStoreType,
3076 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003077 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003078 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3079 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003080
mpagenkoaf801632020-07-03 10:00:42 +00003081 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003082}
khenaidoo7d3c5582021-08-11 18:09:44 -04003083func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05303084 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003085
mpagenkodff5dda2020-08-28 11:52:01 +00003086 for _, field := range flow.GetOfbFields(apFlowItem) {
3087 switch field.Type {
3088 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3089 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003090 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003091 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3092 }
mpagenko01e726e2020-10-23 09:45:29 +00003093 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003094 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3095 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303096 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003097 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303098 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3099 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003100 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3101 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003102 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003103 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303104 return
mpagenkodff5dda2020-08-28 11:52:01 +00003105 }
3106 }
mpagenko01e726e2020-10-23 09:45:29 +00003107 */
mpagenkodff5dda2020-08-28 11:52:01 +00003108 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3109 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303110 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003111 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303112 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003113 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303114 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003115 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003116 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303117 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003118 }
3119 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3120 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303121 *loAddPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003122 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003123 "PCP": loAddPcp})
3124 }
3125 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3126 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003127 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003128 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3129 }
3130 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3131 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003132 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003133 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3134 }
3135 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3136 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003137 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003138 "IPv4-DST": field.GetIpv4Dst()})
3139 }
3140 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3141 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003142 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003143 "IPv4-SRC": field.GetIpv4Src()})
3144 }
3145 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3146 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003147 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003148 "Metadata": field.GetTableMetadata()})
3149 }
3150 /*
3151 default:
3152 {
3153 //all other entires ignored
3154 }
3155 */
3156 }
3157 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303158}
mpagenkodff5dda2020-08-28 11:52:01 +00003159
khenaidoo7d3c5582021-08-11 18:09:44 -04003160func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003161 for _, action := range flow.GetActions(apFlowItem) {
3162 switch action.Type {
3163 /* not used:
3164 case of.OfpActionType_OFPAT_OUTPUT:
3165 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003166 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003167 "Output": action.GetOutput()})
3168 }
3169 */
3170 case of.OfpActionType_OFPAT_PUSH_VLAN:
3171 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003172 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003173 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3174 }
3175 case of.OfpActionType_OFPAT_SET_FIELD:
3176 {
3177 pActionSetField := action.GetSetField()
3178 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003179 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003180 "OxcmClass": pActionSetField.Field.OxmClass})
3181 }
3182 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303183 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003184 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303185 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003186 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303187 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003188 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303189 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003190 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003191 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003192 "Type": pActionSetField.Field.GetOfbField().Type})
3193 }
3194 }
3195 /*
3196 default:
3197 {
3198 //all other entires ignored
3199 }
3200 */
3201 }
3202 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303203}
3204
3205//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003206func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003207 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303208 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3209 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
3210 var loAddPcp, loSetPcp uint8
3211 var loIPProto uint32
3212 /* the TechProfileId is part of the flow Metadata - compare also comment within
3213 * OLT-Adapter:openolt_flowmgr.go
3214 * Metadata 8 bytes:
3215 * Most Significant 2 Bytes = Inner VLAN
3216 * Next 2 Bytes = Tech Profile ID(TPID)
3217 * Least Significant 4 Bytes = Port ID
3218 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3219 * subscriber related flows.
3220 */
3221
dbainbri4d3a0dc2020-12-02 00:33:42 +00003222 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303223 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003224 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003225 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003226 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303227 }
mpagenko551a4d42020-12-08 18:09:20 +00003228 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003229 loCookie := apFlowItem.GetCookie()
3230 loCookieSlice := []uint64{loCookie}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003231 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003232 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05303233
dbainbri4d3a0dc2020-12-02 00:33:42 +00003234 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003235 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303236 if loIPProto == 2 {
3237 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3238 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003239 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003240 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303241 return nil
3242 }
mpagenko01e726e2020-10-23 09:45:29 +00003243 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003244 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003245
3246 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003247 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003248 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003249 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3250 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3251 //TODO!!: Use DeviceId within the error response to rwCore
3252 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003253 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003254 }
3255 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003256 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003257 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3258 } else {
3259 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3260 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3261 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303262 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003263 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003264 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003265 }
mpagenko9a304ea2020-12-16 15:54:01 +00003266
khenaidoo42dcdfd2021-10-19 17:34:12 -04003267 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003268 if apFlowMetaData != nil {
3269 meter = apFlowMetaData.Meters[0]
3270 }
mpagenkobc4170a2021-08-17 16:42:10 +00003271 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3272 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3273 // when different rules are requested concurrently for the same uni
3274 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3275 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3276 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003277 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3278 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003279 //SetUniFlowParams() may block on some rule that is suspended-to-add
3280 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003281 // Also the error is returned to caller via response channel
3282 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
3283 loMatchVlan, loSetVlan, loSetPcp, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003284 dh.lockVlanConfig.RUnlock()
3285 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003286 return
mpagenkodff5dda2020-08-28 11:52:01 +00003287 }
mpagenkobc4170a2021-08-17 16:42:10 +00003288 dh.lockVlanConfig.RUnlock()
3289 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003290 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003291 loMatchVlan, loSetVlan, loSetPcp, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003292 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003293 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003294 if err != nil {
3295 *respChan <- err
3296 }
mpagenko01e726e2020-10-23 09:45:29 +00003297}
3298
3299//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003300func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003301 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3302 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3303 //no extra check is done on the rule parameters
3304 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3305 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3306 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3307 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003308 // - 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 +00003309 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003310 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003311
3312 /* TT related temporary workaround - should not be needed anymore
3313 for _, field := range flow.GetOfbFields(apFlowItem) {
3314 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3315 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003316 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003317 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3318 if loIPProto == 2 {
3319 // 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 +00003320 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003321 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003322 return nil
3323 }
3324 }
3325 } //for all OfbFields
3326 */
3327
mpagenko9a304ea2020-12-16 15:54:01 +00003328 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003329 dh.lockVlanConfig.RLock()
3330 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003331 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3332 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003333 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3334 return
mpagenko01e726e2020-10-23 09:45:29 +00003335 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003336 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003337 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003338 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003339 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003340 // Push response on the response channel
3341 if respChan != nil {
3342 // Do it in a non blocking fashion, so that in case the flow handler routine has shutdown for any reason, we do not block here
3343 select {
3344 case *respChan <- nil:
3345 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3346 default:
3347 }
3348 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003349 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003350}
3351
Himani Chawla26e555c2020-08-31 12:30:20 +05303352// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003353// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003354// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003355func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003356 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent cmn.OnuDeviceEvent, lastFlowToReconcile bool, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003357 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003358
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003359 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003360 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003361 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3362 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003363 }
3364
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003365 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3366 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003367 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003368 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003369 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3370 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003371 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3372 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003373 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003374 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3375 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003376 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003377 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003378 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303379 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003380 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003381 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3382 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003383 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003384 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003385 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3386 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003387 }
3388 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003389 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003390 "device-id": dh.DeviceID})
3391 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003392 }
3393 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003394 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003395 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3396 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003397 }
3398 return nil
3399}
3400
mpagenkofc4f56e2020-11-04 17:17:49 +00003401//VerifyVlanConfigRequest checks on existence of a given uniPort
3402// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003403func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003404 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003405 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003406 for _, uniPort := range dh.uniEntityMap {
3407 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003408 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003409 pCurrentUniPort = uniPort
3410 break //found - end search loop
3411 }
3412 }
3413 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003414 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003415 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003416 return
3417 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003418 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003419}
3420
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003421//VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
3422func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003423 //TODO!! verify and start pending flow configuration
3424 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3425 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003426
3427 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003428 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003429 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003430 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003431 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003432 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003433 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003434 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003435 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3436 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003437 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003438 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003439 } else {
3440 /***** UniVlanConfigFsm continued */
3441 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003442 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3443 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003444 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003445 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3446 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003447 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003448 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003449 } else {
3450 /***** UniVlanConfigFsm continued */
3451 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003452 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3453 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003454 }
mpagenkodff5dda2020-08-28 11:52:01 +00003455 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003456 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003457 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3458 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003459 }
3460 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003461 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003462 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3463 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003464 }
3465 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003466 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003467 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003468 }
mpagenkof1fc3862021-02-16 10:09:52 +00003469 } else {
3470 dh.lockVlanConfig.RUnlock()
3471 }
mpagenkodff5dda2020-08-28 11:52:01 +00003472}
3473
3474//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3475// intention is to provide this method to be called from VlanConfigFsm itself, when resources (and methods!) are cleaned up
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003476func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003477 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003478 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003479 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003480 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003481 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003482 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003483}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003484
mpagenkof1fc3862021-02-16 10:09:52 +00003485//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003486func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003487 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3488 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3489 // obviously then parallel processing on the cancel must be avoided
3490 // deadline context to ensure completion of background routines waited for
3491 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3492 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3493 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3494
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003495 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003496 var wg sync.WaitGroup
3497 wg.Add(1) // for the 1 go routine to finish
3498
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003499 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003500 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3501
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003502 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003503}
3504
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003505//StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003506//available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003507func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3508 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003509
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003510 if dh.IsReconciling() {
3511 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003512 return nil
3513 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003514 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003515
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003516 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003517 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003518 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3519 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003520 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003521 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003522
mpagenkof1fc3862021-02-16 10:09:52 +00003523 if aWriteToKvStore {
3524 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3525 }
3526 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003527}
3528
dbainbri4d3a0dc2020-12-02 00:33:42 +00003529func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003530 defer cancel() //ensure termination of context (may be pro forma)
3531 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003532 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003533 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003534}
3535
mpagenkoe4782082021-11-25 12:04:26 +00003536//ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
3537// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
3538func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
3539 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
3540 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
3541 dh.mutexDeviceReason.Lock()
3542 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003543 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003544 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003545 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003546 DeviceId: dh.DeviceID,
3547 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003548 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00003549 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003550 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003551 return err
3552 }
mpagenkoe4782082021-11-25 12:04:26 +00003553 } else {
3554 logger.Debugf(ctx, "update reason in core not requested: %s - device-id: %s", cmn.DeviceReasonMap[deviceReason], dh.DeviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003555 }
mpagenkoe4782082021-11-25 12:04:26 +00003556 dh.deviceReason = deviceReason
3557 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
3558 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003559 return nil
3560}
3561
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003562func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3563 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003564 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003565 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3566 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003567 }
mpagenkof1fc3862021-02-16 10:09:52 +00003568 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003569}
3570
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003571// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003572// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003573func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3574 dh.lockDevice.RLock()
3575 defer dh.lockDevice.RUnlock()
3576 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003577 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003578 }
3579 return 0, errors.New("error-fetching-uni-port")
3580}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003581
3582// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003583func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3584 var errorsList []error
3585 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 -08003586
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003587 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3588 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3589 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3590
3591 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3592 // successfully.
3593 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3594 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3595 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003596 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003597 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003598 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003599 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003600 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003601}
3602
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003603func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3604 var err error
3605 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003606 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003607
3608 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003609 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003610 errorsList = append(errorsList, err)
3611 }
3612 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003613 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003614
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003615 return errorsList
3616}
3617
3618func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3619 var err error
3620 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003621 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003622 // Check if group metric related config is updated
3623 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003624 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3625 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3626 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003627
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003628 if ok && m.Frequency != v.GroupFreq {
3629 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003630 errorsList = append(errorsList, err)
3631 }
3632 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003633 if ok && m.Enabled != v.Enabled {
3634 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003635 errorsList = append(errorsList, err)
3636 }
3637 }
3638 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003639 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003640 return errorsList
3641}
3642
3643func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3644 var err error
3645 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003646 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003647 // Check if standalone metric related config is updated
3648 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003649 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3650 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3651 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003652
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003653 if ok && m.Frequency != v.SampleFreq {
3654 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003655 errorsList = append(errorsList, err)
3656 }
3657 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003658 if ok && m.Enabled != v.Enabled {
3659 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003660 errorsList = append(errorsList, err)
3661 }
3662 }
3663 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003664 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003665 return errorsList
3666}
3667
3668// nolint: gocyclo
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003669func (dh *deviceHandler) StartCollector(ctx context.Context) {
Girish Gowdrae09a6202021-01-12 18:10:59 -08003670 logger.Debugf(ctx, "startingCollector")
3671
3672 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003673 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303674 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003675 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003676 // Initialize the next metric collection time.
3677 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3678 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003679 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003680 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003681 for {
3682 select {
3683 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003684 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003685 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003686 // Stop the L2 PM FSM
3687 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003688 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3689 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3690 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003691 }
3692 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003693 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003694 }
3695 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003696 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3697 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003698 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003699 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3700 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003701 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003702
Girish Gowdrae09a6202021-01-12 18:10:59 -08003703 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003704 case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3705 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3706 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3707 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3708 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003709 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003710 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003711 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003712 } else {
3713 if dh.pmConfigs.Grouped { // metrics are managed as a group
3714 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003715 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003716
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003717 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3718 // 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 -08003719 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003720 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3721 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003722 }
3723 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003724 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3725 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3726 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3727 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003728 }
3729 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003730 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003731
3732 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003733 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3734 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3735 // 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 -08003736 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003737 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3738 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003739 }
3740 }
3741 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003742 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3743 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3744 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3745 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003746 }
3747 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003748 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003749 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003750 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003751 } */
3752 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003753 }
3754 }
3755}
kesavandfdf77632021-01-26 23:40:33 -05003756
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003757func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003758
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003759 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3760 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003761}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003762
Himani Chawla43f95ff2021-06-03 00:24:12 +05303763func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3764 if dh.pOnuMetricsMgr == nil {
3765 return &extension.SingleGetValueResponse{
3766 Response: &extension.GetValueResponse{
3767 Status: extension.GetValueResponse_ERROR,
3768 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3769 },
3770 }
3771 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303772 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303773 return resp
3774}
3775
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003776func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3777 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003778 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003779 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003780 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003781}
3782
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003783func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003784 var pAdapterFsm *cmn.AdapterFsm
3785 //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 +00003786 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003787 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003788 {
mpagenkofbf577d2021-10-12 11:44:33 +00003789 if dh.pOnuOmciDevice != nil {
3790 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3791 } else {
3792 return true //FSM not active - so there is no activity on omci
3793 }
mpagenkof1fc3862021-02-16 10:09:52 +00003794 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003795 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003796 {
mpagenkofbf577d2021-10-12 11:44:33 +00003797 if dh.pOnuOmciDevice != nil {
3798 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3799 } else {
3800 return true //FSM not active - so there is no activity on omci
3801 }
mpagenkof1fc3862021-02-16 10:09:52 +00003802 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003803 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003804 {
mpagenkofbf577d2021-10-12 11:44:33 +00003805 if dh.pLockStateFsm != nil {
3806 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3807 } else {
3808 return true //FSM not active - so there is no activity on omci
3809 }
mpagenkof1fc3862021-02-16 10:09:52 +00003810 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003811 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003812 {
mpagenkofbf577d2021-10-12 11:44:33 +00003813 if dh.pUnlockStateFsm != nil {
3814 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3815 } else {
3816 return true //FSM not active - so there is no activity on omci
3817 }
mpagenkof1fc3862021-02-16 10:09:52 +00003818 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003819 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003820 {
mpagenkofbf577d2021-10-12 11:44:33 +00003821 if dh.pOnuMetricsMgr != nil {
3822 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003823 } else {
3824 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003825 }
3826 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003827 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003828 {
3829 dh.lockUpgradeFsm.RLock()
3830 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003831 if dh.pOnuUpradeFsm != nil {
3832 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3833 } else {
3834 return true //FSM not active - so there is no activity on omci
3835 }
mpagenko80622a52021-02-09 16:53:23 +00003836 }
mpagenkof1fc3862021-02-16 10:09:52 +00003837 default:
3838 {
3839 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003840 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003841 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003842 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003843 }
mpagenkofbf577d2021-10-12 11:44:33 +00003844 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3845 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3846 }
3847 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003848}
3849
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003850func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3851 for _, v := range dh.pOnuTP.PAniConfigFsm {
3852 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003853 return false
3854 }
3855 }
3856 return true
3857}
3858
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003859func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003860 dh.lockVlanConfig.RLock()
3861 defer dh.lockVlanConfig.RUnlock()
3862 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003863 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003864 return false
3865 }
3866 }
3867 return true //FSM not active - so there is no activity on omci
3868}
3869
3870func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3871 dh.lockVlanConfig.RLock()
3872 defer dh.lockVlanConfig.RUnlock()
3873 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003874 if v.PAdaptFsm.PFsm != nil {
3875 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003876 return true //there is at least one VLAN FSM with some active configuration
3877 }
3878 }
3879 }
3880 return false //there is no VLAN FSM with some active configuration
3881}
3882
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003883func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003884 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3885 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3886 return false
3887 }
3888 }
3889 // a further check is done to identify, if at least some data traffic related configuration exists
3890 // 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])
3891 return dh.checkUserServiceExists(ctx)
3892}
3893
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003894func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003895 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3896 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003897 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003898 // TODO: fatal error reset ONU, delete deviceHandler!
3899 return
3900 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003901 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
3902 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003903}
3904
3905func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3906 dh.mutexCollectorFlag.Lock()
3907 dh.collectorIsRunning = flagValue
3908 dh.mutexCollectorFlag.Unlock()
3909}
3910
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003911func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003912 dh.mutexCollectorFlag.RLock()
3913 flagValue := dh.collectorIsRunning
3914 dh.mutexCollectorFlag.RUnlock()
3915 return flagValue
3916}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303917
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303918func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3919 dh.mutextAlarmManagerFlag.Lock()
3920 dh.alarmManagerIsRunning = flagValue
3921 dh.mutextAlarmManagerFlag.Unlock()
3922}
3923
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003924func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303925 dh.mutextAlarmManagerFlag.RLock()
3926 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303927 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303928 dh.mutextAlarmManagerFlag.RUnlock()
3929 return flagValue
3930}
3931
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003932func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303933 logger.Debugf(ctx, "startingAlarmManager")
3934
3935 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003936 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303937 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303938 if stop := <-dh.stopAlarmManager; stop {
3939 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303940 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303941 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003942 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
3943 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05303944 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303945 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003946 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
3947 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05303948 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303949 }
3950}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003951
Girish Gowdrae95687a2021-09-08 16:30:58 -07003952func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
3953 dh.mutexFlowMonitoringRoutineFlag.Lock()
3954 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
3955 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"flag": flag})
3956 dh.isFlowMonitoringRoutineActive[uniID] = flag
3957}
3958
3959func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
3960 dh.mutexFlowMonitoringRoutineFlag.RLock()
3961 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
3962 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
3963 log.Fields{"isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
3964 return dh.isFlowMonitoringRoutineActive[uniID]
3965}
3966
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003967func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
3968 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003969
Maninder7961d722021-06-16 22:10:28 +05303970 connectStatus := voltha.ConnectStatus_UNREACHABLE
3971 operState := voltha.OperStatus_UNKNOWN
3972
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003973 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003974 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003975 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00003976 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003977 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003978 case success := <-dh.chReconcilingFinished:
3979 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003980 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05303981 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003982 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05303983 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00003984 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003985 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05303986 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003987 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
3988 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05303989 operState = voltha.OperStatus_ACTIVE
3990 } else {
3991 operState = voltha.OperStatus_ACTIVATING
3992 }
3993 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003994 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
3995 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
3996 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05303997 operState = voltha.OperStatus_DISCOVERED
3998 }
mpagenko2c3f6c52021-11-23 11:22:10 +00003999 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninderb5187552021-03-23 22:23:42 +05304000 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304001 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004002 logger.Debugw(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004003 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004004 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004005 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004006 ConnStatus: connectStatus,
4007 OperStatus: operState,
4008 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304009 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004010 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304011 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004012 } else {
Maninderb5187552021-03-23 22:23:42 +05304013 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004014 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304015
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004016 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304017 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004018 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004019 } else {
4020 onuDevEntry.MutexPersOnuConfig.RLock()
4021 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4022 connectStatus = voltha.ConnectStatus_REACHABLE
4023 }
4024 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304025 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004026 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004027 }
mpagenko101ac942021-11-16 15:01:29 +00004028 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004029 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004030 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304031
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004032 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304033 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004034 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004035 } else {
4036 onuDevEntry.MutexPersOnuConfig.RLock()
4037 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4038 connectStatus = voltha.ConnectStatus_REACHABLE
4039 }
4040 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304041 }
4042
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004043 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304044
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004045 }
4046 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004047 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004048 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004049 dh.SetReconcilingReasonUpdate(false)
4050
4051 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4052 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4053 } else {
4054 onuDevEntry.MutexReconciledTpInstances.Lock()
4055 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
4056 onuDevEntry.MutexReconciledTpInstances.Unlock()
4057 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004058 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004059 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004060 dh.mutexReconcilingFlag.Lock()
4061 if skipOnuConfig {
4062 dh.reconciling = cSkipOnuConfigReconciling
4063 } else {
4064 dh.reconciling = cOnuConfigReconciling
4065 }
4066 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004067}
4068
mpagenko101ac942021-11-16 15:01:29 +00004069func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004070 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
4071 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004072 dh.sendChReconcileFinished(success)
4073 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4074 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4075 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004076 } else {
mpagenko101ac942021-11-16 15:01:29 +00004077 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004078 }
4079}
4080
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004081func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004082 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004083 defer dh.mutexReconcilingFlag.RUnlock()
4084 return dh.reconciling != cNoReconciling
4085}
4086
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004087func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004088 dh.mutexReconcilingFlag.RLock()
4089 defer dh.mutexReconcilingFlag.RUnlock()
4090 return dh.reconciling == cSkipOnuConfigReconciling
4091}
4092
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004093func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4094 dh.mutexReconcilingReasonUpdate.Lock()
4095 dh.reconcilingReasonUpdate = value
4096 dh.mutexReconcilingReasonUpdate.Unlock()
4097}
4098
4099func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4100 dh.mutexReconcilingReasonUpdate.RLock()
4101 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4102 return dh.reconcilingReasonUpdate
4103}
4104
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004105func (dh *deviceHandler) getDeviceReason() uint8 {
4106 dh.mutexDeviceReason.RLock()
4107 value := dh.deviceReason
4108 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004109 return value
4110}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004111
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004112func (dh *deviceHandler) GetDeviceReasonString() string {
4113 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004114}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004115
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004116func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004117 dh.mutexReadyForOmciConfig.Lock()
4118 dh.readyForOmciConfig = flagValue
4119 dh.mutexReadyForOmciConfig.Unlock()
4120}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004121func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004122 dh.mutexReadyForOmciConfig.RLock()
4123 flagValue := dh.readyForOmciConfig
4124 dh.mutexReadyForOmciConfig.RUnlock()
4125 return flagValue
4126}
Maninder7961d722021-06-16 22:10:28 +05304127
4128func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004129 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304130 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004131 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304132 }
4133
4134 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004135 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004136 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004137 ConnStatus: connectStatus,
4138 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4139 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304140 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004141 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304142 }
4143}
khenaidoo7d3c5582021-08-11 18:09:44 -04004144
4145/*
4146Helper functions to communicate with Core
4147*/
4148
4149func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4150 cClient, err := dh.coreClient.GetCoreServiceClient()
4151 if err != nil || cClient == nil {
4152 return nil, err
4153 }
4154 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4155 defer cancel()
4156 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4157 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4158}
4159
khenaidoo42dcdfd2021-10-19 17:34:12 -04004160func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004161 cClient, err := dh.coreClient.GetCoreServiceClient()
4162 if err != nil || cClient == nil {
4163 return err
4164 }
4165 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4166 defer cancel()
4167 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
4168 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-state": deviceStateFilter, "error": err})
4169 return err
4170}
4171
4172func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4173 cClient, err := dh.coreClient.GetCoreServiceClient()
4174 if err != nil || cClient == nil {
4175 return err
4176 }
4177 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4178 defer cancel()
4179 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
4180 logger.Debugw(subCtx, "pmconfig-updated-in-core", log.Fields{"pm-configs": pmConfigs, "error": err})
4181 return err
4182}
4183
4184func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4185 cClient, err := dh.coreClient.GetCoreServiceClient()
4186 if err != nil || cClient == nil {
4187 return err
4188 }
4189 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4190 defer cancel()
4191 _, err = cClient.DeviceUpdate(subCtx, device)
4192 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4193 return err
4194}
4195
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004196func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004197 cClient, err := dh.coreClient.GetCoreServiceClient()
4198 if err != nil || cClient == nil {
4199 return err
4200 }
4201 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4202 defer cancel()
4203 _, err = cClient.PortCreated(subCtx, port)
4204 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4205 return err
4206}
4207
khenaidoo42dcdfd2021-10-19 17:34:12 -04004208func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004209 cClient, err := dh.coreClient.GetCoreServiceClient()
4210 if err != nil || cClient == nil {
4211 return err
4212 }
4213 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4214 defer cancel()
4215 _, err = cClient.PortStateUpdate(subCtx, portState)
4216 logger.Debugw(subCtx, "port-state-updated-in-core", log.Fields{"port-state": portState, "error": err})
4217 return err
4218}
4219
khenaidoo42dcdfd2021-10-19 17:34:12 -04004220func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004221 cClient, err := dh.coreClient.GetCoreServiceClient()
4222 if err != nil || cClient == nil {
4223 return err
4224 }
4225 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4226 defer cancel()
4227 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
4228 logger.Debugw(subCtx, "device-reason-updated-in-core", log.Fields{"reason": reason, "error": err})
4229 return err
4230}
4231
4232/*
4233Helper functions to communicate with parent adapter
4234*/
4235
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004236func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4237 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4238
4239 var request = ia.TechProfileInstanceRequestMessage{
4240 DeviceId: dh.DeviceID,
4241 TpInstancePath: aTpPath,
4242 ParentDeviceId: dh.parentID,
4243 ParentPonPort: dh.device.ParentPortNo,
4244 OnuId: dh.device.ProxyAddress.OnuId,
4245 UniId: uint32(aUniID),
4246 }
4247
4248 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004249 if err != nil || pgClient == nil {
4250 return nil, err
4251 }
4252 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4253 defer cancel()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004254 logger.Debugw(subCtx, "get-tech-profile-instance", log.Fields{"request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
4255 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004256}
4257
Girish Gowdrae95687a2021-09-08 16:30:58 -07004258// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4259// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4260func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4261 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4262 dh.setFlowMonitoringIsRunning(uniID, true)
4263 for {
4264 select {
4265 // block on the channel to receive an incoming flow
4266 // process the flow completely before proceeding to handle the next flow
4267 case flowCb := <-dh.flowCbChan[uniID]:
4268 startTime := time.Now()
4269 logger.Debugw(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
4270 respChan := make(chan error)
4271 if flowCb.addFlow {
4272 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4273 } else {
4274 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4275 }
4276 // Block on response and tunnel it back to the caller
4277 *flowCb.respChan <- <-respChan
4278 logger.Debugw(flowCb.ctx, "serial-flow-processor--end",
4279 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4280 case <-dh.stopFlowMonitoringRoutine[uniID]:
4281 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4282 dh.setFlowMonitoringIsRunning(uniID, false)
4283 return
4284 }
4285 }
4286}
4287
khenaidoo42dcdfd2021-10-19 17:34:12 -04004288func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004289 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4290 if err != nil || pgClient == nil {
4291 return err
4292 }
4293 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4294 defer cancel()
4295 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4296 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4297 if err != nil {
4298 logger.Errorw(ctx, "omci-failure", log.Fields{"request": request, "error": err, "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
4299 }
4300 return err
4301}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004302
4303// GetDeviceID - TODO: add comment
4304func (dh *deviceHandler) GetDeviceID() string {
4305 return dh.DeviceID
4306}
4307
4308// GetProxyAddressID - TODO: add comment
4309func (dh *deviceHandler) GetProxyAddressID() string {
4310 return dh.device.ProxyAddress.GetDeviceId()
4311}
4312
4313// GetProxyAddressType - TODO: add comment
4314func (dh *deviceHandler) GetProxyAddressType() string {
4315 return dh.device.ProxyAddress.GetDeviceType()
4316}
4317
4318// GetProxyAddress - TODO: add comment
4319func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4320 return dh.device.ProxyAddress
4321}
4322
4323// GetEventProxy - TODO: add comment
4324func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4325 return dh.EventProxy
4326}
4327
4328// GetOmciTimeout - TODO: add comment
4329func (dh *deviceHandler) GetOmciTimeout() int {
4330 return dh.pOpenOnuAc.omciTimeout
4331}
4332
4333// GetAlarmAuditInterval - TODO: add comment
4334func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4335 return dh.pOpenOnuAc.alarmAuditInterval
4336}
4337
4338// GetDlToOnuTimeout4M - TODO: add comment
4339func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4340 return dh.pOpenOnuAc.dlToOnuTimeout4M
4341}
4342
4343// GetUniEntityMap - TODO: add comment
4344func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4345 return &dh.uniEntityMap
4346}
4347
4348// GetPonPortNumber - TODO: add comment
4349func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4350 return &dh.ponPortNumber
4351}
4352
4353// GetUniVlanConfigFsm - TODO: add comment
4354func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004355 dh.lockVlanConfig.RLock()
4356 value := dh.UniVlanConfigFsmMap[uniID]
4357 dh.lockVlanConfig.RUnlock()
4358 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004359}
4360
4361// GetOnuAlarmManager - TODO: add comment
4362func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4363 return dh.pAlarmMgr
4364}
4365
4366// GetOnuMetricsManager - TODO: add comment
4367func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4368 return dh.pOnuMetricsMgr
4369}
4370
4371// GetOnuTP - TODO: add comment
4372func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4373 return dh.pOnuTP
4374}
4375
4376// GetBackendPathPrefix - TODO: add comment
4377func (dh *deviceHandler) GetBackendPathPrefix() string {
4378 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4379}
4380
4381// GetOnuIndication - TODO: add comment
4382func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4383 return dh.pOnuIndication
4384}
4385
4386// RLockMutexDeletionInProgressFlag - TODO: add comment
4387func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4388 dh.mutexDeletionInProgressFlag.RLock()
4389}
4390
4391// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4392func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4393 dh.mutexDeletionInProgressFlag.RUnlock()
4394}
4395
4396// GetDeletionInProgress - TODO: add comment
4397func (dh *deviceHandler) GetDeletionInProgress() bool {
4398 return dh.deletionInProgress
4399}
4400
4401// GetPmConfigs - TODO: add comment
4402func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4403 return dh.pmConfigs
4404}
4405
4406// GetDeviceType - TODO: add comment
4407func (dh *deviceHandler) GetDeviceType() string {
4408 return dh.DeviceType
4409}
4410
4411// GetLogicalDeviceID - TODO: add comment
4412func (dh *deviceHandler) GetLogicalDeviceID() string {
4413 return dh.logicalDeviceID
4414}
4415
4416// GetDevice - TODO: add comment
4417func (dh *deviceHandler) GetDevice() *voltha.Device {
4418 return dh.device
4419}
4420
4421// GetMetricsEnabled - TODO: add comment
4422func (dh *deviceHandler) GetMetricsEnabled() bool {
4423 return dh.pOpenOnuAc.MetricsEnabled
4424}
4425
4426// InitPmConfigs - TODO: add comment
4427func (dh *deviceHandler) InitPmConfigs() {
4428 dh.pmConfigs = &voltha.PmConfigs{}
4429}
4430
4431// GetUniPortMask - TODO: add comment
4432func (dh *deviceHandler) GetUniPortMask() int {
4433 return dh.pOpenOnuAc.config.UniPortMask
4434}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00004435
4436func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
4437 tpPathFound := false
4438 for _, tpPath := range aTpPathMap {
4439 if tpPath != "" {
4440 tpPathFound = true
4441 }
4442 }
4443 return tpPathFound
4444}