blob: a26246c13b54eaafa4f3ef2c19b2ad1935c9449d [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
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000309 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
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
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000327 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "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 {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000330 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"device-id": device.Id, "err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000331 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000332 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "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 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000358 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
359 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530360 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000361 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
362 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530363}
364
khenaidoo42dcdfd2021-10-19 17:34:12 -0400365func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000366 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000367
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000368 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000369 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000370 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
371 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000372 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530373 if dh.pOnuTP == nil {
374 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000375 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000376 log.Fields{"device-id": dh.DeviceID})
377 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530378 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000379 if !dh.IsReadyForOmciConfig() {
380 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
381 "device-state": dh.GetDeviceReasonString()})
382 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530383 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000384 //previous state test here was just this one, now extended for more states to reject the SetRequest:
385 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
386 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530387
Himani Chawla26e555c2020-08-31 12:30:20 +0530388 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000389 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
390 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000391 dh.pOnuTP.LockTpProcMutex()
392 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000393
mpagenko44bd8362021-11-15 11:40:05 +0000394 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000395 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000396 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000397 }
398 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000399 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800400 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700401 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800402 return err
403 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000404 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
405 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000406
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000407 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530408
Girish Gowdra50e56422021-06-01 16:46:04 -0700409 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400410 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000411 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
412 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700413 // if there has been some change for some uni TechProfilePath
414 //in order to allow concurrent calls to other dh instances we do not wait for execution here
415 //but doing so we can not indicate problems to the caller (who does what with that then?)
416 //by now we just assume straightforward successful execution
417 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
418 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530419
Girish Gowdra50e56422021-06-01 16:46:04 -0700420 // deadline context to ensure completion of background routines waited for
421 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
422 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
423 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000424
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000425 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700426
427 var wg sync.WaitGroup
428 wg.Add(1) // for the 1 go routine to finish
429 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000430 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700431 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000432 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
433 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 -0700434 return tpErr
435 }
436 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
437 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000438 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700439 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000440 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700441 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000442 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
443 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 -0700444 return kvErr
445 }
446 return nil
447 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000448 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700449 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700450 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530451 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000452 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000453 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
454 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530455 return nil
456}
457
khenaidoo42dcdfd2021-10-19 17:34:12 -0400458func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000459 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530460
461 if dh.pOnuTP == nil {
462 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000463 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000464 log.Fields{"device-id": dh.DeviceID})
465 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530466 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530467 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000468 dh.pOnuTP.LockTpProcMutex()
469 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530470
mpagenko0f543222021-11-03 16:24:14 +0000471 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
472 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
473 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000474 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000475 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000476 }
477 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000478 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800479 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000480 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
481 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800482 return err
483 }
mpagenko0f543222021-11-03 16:24:14 +0000484 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
485 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000486 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000487
Mahir Gunyel9545be22021-07-04 15:53:16 -0700488 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000489 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000490
Himani Chawla26e555c2020-08-31 12:30:20 +0530491}
492
khenaidoo42dcdfd2021-10-19 17:34:12 -0400493func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000494 logger.Infow(ctx, "delete-tcont-request start", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000495
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000496 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000497 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000498 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
499 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000500 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530501 if dh.pOnuTP == nil {
502 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000503 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000504 log.Fields{"device-id": dh.DeviceID})
505 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530506 }
507
Himani Chawla26e555c2020-08-31 12:30:20 +0530508 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000509 dh.pOnuTP.LockTpProcMutex()
510 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000511
mpagenko0f543222021-11-03 16:24:14 +0000512 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
513 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
514 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000515 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000516 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000517 }
518 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700519 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000520 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800521 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000522 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
523 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800524 return err
525 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000526 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 +0000527
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000528 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530529
Mahir Gunyel9545be22021-07-04 15:53:16 -0700530 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000531 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000532
Mahir Gunyel9545be22021-07-04 15:53:16 -0700533}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000534
Mahir Gunyel9545be22021-07-04 15:53:16 -0700535func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000536 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
537 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700538 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000539 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
540 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530541 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700542 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000543 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700544 resourceName = "Gem"
545 } else {
546 resourceName = "Tcont"
547 }
548
549 // deadline context to ensure completion of background routines waited for
550 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
551 dctx, cancel := context.WithDeadline(context.Background(), deadline)
552
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000553 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700554
555 var wg sync.WaitGroup
556 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000557 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700558 resource, entryID, &wg)
559 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000560 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
561 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700562 return err
563 }
564
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000565 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
566 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
567 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
568 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700569 var wg2 sync.WaitGroup
570 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
571 wg2.Add(1)
572 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000573 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
574 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700575 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000576 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
577 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700578 return err
579 }
580 }
581 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000582 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700583 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530584 return nil
585}
586
mpagenkodff5dda2020-08-28 11:52:01 +0000587//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000588func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400589 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400590 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700591 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
592 var errorsList []error
593 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000594 //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 +0000595 if apOfFlowChanges.ToRemove != nil {
596 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000597 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000598 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000599 "device-id": dh.DeviceID})
600 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700601 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000602 continue
603 }
604 flowInPort := flow.GetInPort(flowItem)
605 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000606 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
607 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700608 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000609 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000610 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000611 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000612 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000613 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000614 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000615 continue
616 } else {
617 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000618 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000619 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
620 loUniPort = uniPort
621 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000622 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000623 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000624 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000625 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700626 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000627 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000628 }
629 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000630 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000631 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
632 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700633
634 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
635 // Step1 : Fill flowControlBlock
636 // Step2 : Push the flowControlBlock to ONU channel
637 // Step3 : Wait on response channel for response
638 // Step4 : Return error value
639 startTime := time.Now()
640 respChan := make(chan error)
641 flowCb := FlowCb{
642 ctx: ctx,
643 addFlow: false,
644 flowItem: flowItem,
645 flowMetaData: nil,
646 uniPort: loUniPort,
647 respChan: &respChan,
648 }
649 dh.flowCbChan[loUniPort.UniID] <- flowCb
650 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
651 // Wait on the channel for flow handlers return value
652 retError = <-respChan
653 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
654 if retError != nil {
655 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
656 log.Fields{"device-id": dh.DeviceID, "error": retError})
657 errorsList = append(errorsList, retError)
658 continue
659 }
660 } else {
661 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
662 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000663 }
664 }
665 }
666 }
mpagenko01e726e2020-10-23 09:45:29 +0000667 if apOfFlowChanges.ToAdd != nil {
668 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
669 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000670 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000671 "device-id": dh.DeviceID})
672 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700673 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000674 continue
675 }
676 flowInPort := flow.GetInPort(flowItem)
677 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000678 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
679 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700680 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000681 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000682 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000683 } else if flowInPort == dh.ponPortNumber {
684 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000685 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000686 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000687 continue
688 } else {
689 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000690 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000691 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
692 loUniPort = uniPort
693 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000694 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000695 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000696 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000697 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700698 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000699 continue
mpagenko01e726e2020-10-23 09:45:29 +0000700 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000701 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
702 // if not, we just throw some error here to have an indication about that, if we really need to support that
703 // then we would need to create some means to activate the internal stored flows
704 // after the device gets active automatically (and still with its dependency to the TechProfile)
705 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
706 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000707 if !dh.IsReadyForOmciConfig() {
708 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
709 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700710 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
711 errorsList = append(errorsList, retError)
712 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000713 }
714
mpagenko01e726e2020-10-23 09:45:29 +0000715 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000716 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000717 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
718 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700719 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
720 // Step1 : Fill flowControlBlock
721 // Step2 : Push the flowControlBlock to ONU channel
722 // Step3 : Wait on response channel for response
723 // Step4 : Return error value
724 startTime := time.Now()
725 respChan := make(chan error)
726 flowCb := FlowCb{
727 ctx: ctx,
728 addFlow: true,
729 flowItem: flowItem,
730 flowMetaData: apFlowMetaData,
731 uniPort: loUniPort,
732 respChan: &respChan,
733 }
734 dh.flowCbChan[loUniPort.UniID] <- flowCb
735 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
736 // Wait on the channel for flow handlers return value
737 retError = <-respChan
738 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
739 if retError != nil {
740 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
741 log.Fields{"device-id": dh.DeviceID, "error": retError})
742 errorsList = append(errorsList, retError)
743 continue
744 }
745 } else {
746 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
747 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000748 }
749 }
750 }
751 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700752 if len(errorsList) > 0 {
753 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
754 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
755 }
756 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000757}
758
Himani Chawla6d2ae152020-09-02 13:11:20 +0530759//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000760//following are the expected device states after this activity:
761//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
762// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000763func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
764 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000765
mpagenko900ee4b2020-10-12 11:56:34 +0000766 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000767 //note that disableDevice sequences in some 'ONU active' state may yield also
768 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000769 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000770 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000771 //disable-device shall be just a UNi/ONU-G related admin state setting
772 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000773
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000774 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000775 // disable UNI ports/ONU
776 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
777 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000778 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000779 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000780 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000781 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000782 }
783 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000784 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000785 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000786 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400787 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000788 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000789 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400790 OperStatus: voltha.OperStatus_UNKNOWN,
791 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000792 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000793 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000794 }
mpagenko01e726e2020-10-23 09:45:29 +0000795 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000796
797 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000798 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000799 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300800 }
801}
802
Himani Chawla6d2ae152020-09-02 13:11:20 +0530803//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000804func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
805 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000806
mpagenkoaa3afe92021-05-21 16:20:58 +0000807 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000808 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
809 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
810 // for real ONU's that should have nearly no influence
811 // Note that for real ONU's there is anyway a problematic situation with following sequence:
812 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
813 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
814 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000815 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000816
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000817 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000818 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000819 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000820 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000821 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000822 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000823 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000824 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300825}
826
dbainbri4d3a0dc2020-12-02 00:33:42 +0000827func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000828 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000829
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000830 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000831 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000832 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000833 return
834 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000835 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000836 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000837 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000838 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000839 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000840 }
mpagenko101ac942021-11-16 15:01:29 +0000841 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000842 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000843 }
Himani Chawla4d908332020-08-31 12:30:20 +0530844 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000845 pDevEntry.MutexPersOnuConfig.RLock()
846 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
847 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
848 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
849 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
850 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000851 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000852}
853
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000854func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000855 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000856
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000857 continueWithFlowConfig := false
858
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000859 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000860 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000861 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000862 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
863 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000864 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000865 dh.pOnuTP.LockTpProcMutex()
866 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000867
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000868 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000869 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000870 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
871 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000872 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000873 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000874 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
875 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000876 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000877 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700878 techProfsFound := false
879 techProfInstLoadFailed := false
880outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000881 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000882 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000883 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000884 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000885 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000886 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000887 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000888 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000889 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
890 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000891 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000892 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000893 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700894 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000895 var iaTechTpInst ia.TechProfileDownloadMessage
896 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800897 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000898 pDevEntry.MutexReconciledTpInstances.RLock()
899 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
900 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000901 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000902 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700903 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000904 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700905 break outerLoop
906 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000907 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000908 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700909 var tpInst tech_profile.TechProfileInstance
910 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400911 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700912 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000913 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000914 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700915 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000916 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000917 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700918 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
919 break outerLoop
920 }
921
Girish Gowdra041dcb32020-11-16 16:54:30 -0800922 // deadline context to ensure completion of background routines waited for
923 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
924 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000925 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000926
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000927 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800928 var wg sync.WaitGroup
929 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000930 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000931 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000932 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
933 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700934 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
935 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800936 }
mpagenko2dc896e2021-08-02 12:03:59 +0000937 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000938 if len(uniData.PersFlowParams) != 0 {
939 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000940 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000941 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000942 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000943 } // for all UNI entries from SOnuPersistentData
944 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
945 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000946 }
mpagenko2dc896e2021-08-02 12:03:59 +0000947
948 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
949 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000950
951 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +0000952}
953
954func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
955 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
956 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000957 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000958 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000959 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000960 return
961 }
mpagenko2dc896e2021-08-02 12:03:59 +0000962 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000963 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +0000964 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -0700965 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000966 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000967 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000968 }
mpagenko2dc896e2021-08-02 12:03:59 +0000969 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000970 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000971 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000972 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000973 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000974}
975
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000976func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
977 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000978
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000979 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000980 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000981 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000982 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000983 return
984 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000985
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000986 pDevEntry.MutexPersOnuConfig.RLock()
987 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
988 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000989 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000990 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000991 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000992 return
993 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000994 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +0000995 var uniVlanConfigEntries []uint8
996 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
997
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000998 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000999 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1000 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001001 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001002 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001003 continue
1004 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001005 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001006 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001007 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001008 // It doesn't make sense to configure any flows if no TPs are available
1009 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001010 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001011 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1012 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001013 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001014 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001015
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001016 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001017 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001018 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001019 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001020 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1021 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001022 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001023 return
1024 }
mpagenko101ac942021-11-16 15:01:29 +00001025 //needed to split up function due to sca complexity
1026 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1027
mpagenko2dc896e2021-08-02 12:03:59 +00001028 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001029 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001030 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1031 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001032 // this can't be used as global finished reconciling flag because
1033 // assumes is getting called before the state machines for the last flow is completed,
1034 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001035 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1036 } // for all UNI entries from SOnuPersistentData
1037 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001038
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001039 if !flowsFound {
1040 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001041 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001042 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001043 return
1044 }
mpagenko101ac942021-11-16 15:01:29 +00001045
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001046 if dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00001047 //only with 'SkipOnuConfig' we need to wait for all finished-signals
1048 // from vlanConfig processing of all UNI's.
1049 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1050 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1051 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1052 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1053 log.Fields{"device-id": dh.DeviceID})
1054 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1055 if pDevEntry != nil {
1056 pDevEntry.SendChReconcilingFlowsFinished(true)
1057 }
1058 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001059 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
mpagenko101ac942021-11-16 15:01:29 +00001060 log.Fields{"device-id": dh.DeviceID})
1061 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1062 if pDevEntry != nil {
1063 pDevEntry.SendChReconcilingFlowsFinished(false)
1064 }
1065 return
1066 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001067 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001068 }
1069}
1070
mpagenko101ac942021-11-16 15:01:29 +00001071func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1072 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1073 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1074 flowsProcessed := 0
1075 lastFlowToReconcile := false
1076 loUniID := apUniPort.UniID
1077 for _, flowData := range aPersFlowParam {
1078 if dh.IsSkipOnuConfigReconciling() {
1079 if !(*apFlowsFound) {
1080 *apFlowsFound = true
1081 syncChannel := make(chan struct{})
1082 // start go routine with select() on reconciling vlan config channel before
1083 // starting vlan config reconciling process to prevent loss of any signal
1084 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1085 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1086 //block until the wait routine is really blocked on channel input
1087 // in order to prevent to early ready signal from VlanConfig processing
1088 <-syncChannel
1089 }
1090 if flowsProcessed == len(aPersFlowParam)-1 {
1091 var uniAdded bool
1092 lastFlowToReconcile = true
1093 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1094 apWaitGroup.Add(1) //increment the waiting group
1095 }
1096 }
1097 }
1098 // note for above block: also lastFlowToReconcile (as parameter to flow config below)
1099 // is only relevant in the vlanConfig processing for IsSkipOnuConfigReconciling = true
1100 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1101 "device-id": dh.DeviceID, "uni-id": loUniID,
1102 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1103 dh.lockVlanConfig.Lock()
1104 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1105 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1106 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
1107 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1108 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter, nil); err != nil {
1109 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1110 }
1111 } else {
1112 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
1113 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1114 uint8(flowData.VlanRuleParams.SetPcp), cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
1115 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1116 }
1117 }
1118 dh.lockVlanConfig.Unlock()
1119 flowsProcessed++
1120 } //for all flows of this UNI
1121}
1122
1123//waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1124// and decrements the according handler wait group waiting for these indications
1125func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1126 waitGroup *cmn.WaitGroupWithTimeOut) {
1127 var reconciledUniVlanConfigEntries []uint8
1128 var appended bool
1129 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1130 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1131 "device-id": dh.DeviceID, "expiry": expiry})
1132 // indicate blocking on channel now to the caller
1133 aSyncChannel <- struct{}{}
1134 for {
1135 select {
1136 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1137 switch uniIndication {
1138 // no activity requested (should normally not be received) - just continue waiting
1139 case cWaitReconcileFlowNoActivity:
1140 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1141 case cWaitReconcileFlowAbortOnError:
1142 logger.Debugw(ctx, "waitReconcileFlow aborted on error",
1143 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1144 return
1145 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1146 case cWaitReconcileFlowAbortOnSuccess:
1147 logger.Debugw(ctx, "waitReconcileFlow aborted on success",
1148 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1149 return
1150 // this should be a valid UNI vlan config done indication
1151 default:
1152 if uniIndication < platform.MaxUnisPerOnu {
1153 logger.Debugw(ctx, "reconciling flows has been finished in time for this UNI",
1154 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1155 if reconciledUniVlanConfigEntries, appended =
1156 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1157 waitGroup.Done()
1158 }
1159 } else {
1160 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored",
1161 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1162 }
1163 } //switch uniIndication
1164
1165 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1166 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1167 log.Fields{"device-id": dh.DeviceID})
1168 return
1169 }
1170 }
1171}
1172
1173func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1174 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1175}
1176
1177func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1178 for _, ele := range slice {
1179 if ele == val {
1180 return slice, false
1181 }
1182 }
1183 return append(slice, val), true
1184}
1185
1186// sendChReconcileFinished - sends true or false on reconcileFinish channel
1187func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1188 if dh != nil { //if the object still exists (might have been already deleted in background)
1189 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1190 select {
1191 case dh.chReconcilingFinished <- success:
1192 default:
1193 }
1194 }
1195}
1196
1197// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1198func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1199 if dh != nil { //if the object still exists (might have been already deleted in background)
1200 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1201 select {
1202 case dh.chUniVlanConfigReconcilingDone <- value:
1203 default:
1204 }
1205 }
1206}
1207
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001208func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001209 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001210 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001211}
1212
dbainbri4d3a0dc2020-12-02 00:33:42 +00001213func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001214 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001215
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001216 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001217 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001218 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001219 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001220 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001221 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001222
1223 // deadline context to ensure completion of background routines waited for
1224 //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 +05301225 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001226 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001227
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001228 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001229
1230 var wg sync.WaitGroup
1231 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001232 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001233 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001234
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001235 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001236 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001237}
1238
mpagenko15ff4a52021-03-02 10:09:20 +00001239//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1240// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001241// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001242//was and is called in background - error return does not make sense
1243func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001244 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001245 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001246 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001247 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001248 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001249 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301250 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001251 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001252 return
Himani Chawla4d908332020-08-31 12:30:20 +05301253 }
mpagenko01e726e2020-10-23 09:45:29 +00001254
1255 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001256 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001257
mpagenko44bd8362021-11-15 11:40:05 +00001258 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001259 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001260 // 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 -04001261 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001262 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001263 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001264 OperStatus: voltha.OperStatus_DISCOVERED,
1265 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001266 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001267 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001268 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001269 }
mpagenkoe4782082021-11-25 12:04:26 +00001270 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001271 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001272 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001273 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001274 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1275 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1276 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1277 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001278}
1279
mpagenkoc8bba412021-01-15 15:38:44 +00001280//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001281// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001282func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001283 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001284 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001285 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001286
1287 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001288 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001289 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001290 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1291 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001292 }
1293
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001294 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001295 var inactiveImageID uint16
1296 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1297 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001298 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1299 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001300 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001301 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001302 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001303 if err == nil {
1304 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1305 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001306 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001307 }
1308 } else {
1309 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001310 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001311 }
mpagenko15ff4a52021-03-02 10:09:20 +00001312 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001313 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001314 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001315 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1316 dh.upgradeCanceled = true
1317 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1318 }
mpagenko38662d02021-08-11 09:45:19 +00001319 //no effort spent anymore for the old API to automatically cancel and restart the download
1320 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001321 }
mpagenko15ff4a52021-03-02 10:09:20 +00001322 } else {
1323 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001324 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001325 }
1326 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001327 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1328 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001329 }
1330 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001331}
1332
mpagenkoc26d4c02021-05-06 14:27:57 +00001333//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1334// after the OnuImage has been downloaded to the adapter, called in background
1335func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001336 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001337
1338 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001339 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001340 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001341 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001342 return
1343 }
1344
1345 var inactiveImageID uint16
1346 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1347 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001348 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001349
mpagenko59862f02021-10-11 08:53:18 +00001350 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001351 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001352 // but must be still locked at calling createOnuUpgradeFsm
1353 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1354 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1355 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001356 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1357 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001358 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001359 //flush the remove upgradeFsmChan channel
1360 select {
1361 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001362 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001363 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001364 }
mpagenko59862f02021-10-11 08:53:18 +00001365 dh.lockUpgradeFsm.Unlock()
1366 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1367 dh.upgradeCanceled = true
1368 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1369 }
mpagenko38662d02021-08-11 09:45:19 +00001370 select {
1371 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001372 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001373 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1374 return
1375 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001376 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001377 }
mpagenko59862f02021-10-11 08:53:18 +00001378 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001379 }
mpagenko38662d02021-08-11 09:45:19 +00001380
1381 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001382 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001383 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001384 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001385 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001386 if err == nil {
1387 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1388 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1389 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001390 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001391 return
1392 }
mpagenko38662d02021-08-11 09:45:19 +00001393 } else {
1394 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001395 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001396 }
1397 return
1398 }
1399 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001400 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001401}
1402
1403//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001404func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1405 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001406 var err error
1407 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1408 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1409 // 2.) activation of the inactive image
1410
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001411 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001412 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001413 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1414 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001415 }
1416 dh.lockUpgradeFsm.RLock()
1417 if dh.pOnuUpradeFsm != nil {
1418 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001419 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001420 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001421 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1422 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001423 }
mpagenko59862f02021-10-11 08:53:18 +00001424 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1425 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1426 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1427 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001428 // use the OnuVendor identification from this device for the internal unique name
1429 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001430 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001431 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001432 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001433 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001434 "device-id": dh.DeviceID, "error": err})
1435 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001436 }
mpagenko183647c2021-06-08 15:25:04 +00001437 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001438 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001439 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001440 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001441 } //else
1442 dh.lockUpgradeFsm.RUnlock()
1443
1444 // 2.) check if requested image-version equals the inactive one and start its activation
1445 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1446 var inactiveImageID uint16
1447 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1448 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001449 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1450 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001451 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001452 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001453 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001454 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001455 if err == nil {
1456 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1457 inactiveImageID, aCommitRequest); err != nil {
1458 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001459 "device-id": dh.DeviceID, "error": err})
1460 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001461 }
1462 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001463 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001464 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001465 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001466 } //else
1467 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001468 "device-id": dh.DeviceID, "error": err})
1469 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001470}
1471
1472//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001473func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1474 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001475 var err error
1476 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1477 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1478 // 2.) commitment of the active image
1479
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001480 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001481 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001482 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1483 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001484 }
1485 dh.lockUpgradeFsm.RLock()
1486 if dh.pOnuUpradeFsm != nil {
1487 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001488 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001489 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001490 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1491 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001492 }
mpagenko59862f02021-10-11 08:53:18 +00001493 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1494 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1495 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1496 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001497 // use the OnuVendor identification from this device for the internal unique name
1498 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001499 // 1.) check a started upgrade process and relay the commitment request to it
1500 // the running upgrade may be based either on the imageIdentifier (started from download)
1501 // or on the imageVersion (started from pure activation)
1502 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1503 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001504 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001505 "device-id": dh.DeviceID, "error": err})
1506 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001507 }
mpagenko183647c2021-06-08 15:25:04 +00001508 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001509 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001510 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001511 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001512 } //else
1513 dh.lockUpgradeFsm.RUnlock()
1514
mpagenko183647c2021-06-08 15:25:04 +00001515 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001516 var activeImageID uint16
1517 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1518 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001519 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1520 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001521 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001522 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001523 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001524 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001525 if err == nil {
1526 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1527 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001528 "device-id": dh.DeviceID, "error": err})
1529 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001530 }
1531 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001532 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001533 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001534 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001535 } //else
1536 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001537 "device-id": dh.DeviceID, "error": err})
1538 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001539}
1540
mpagenkoaa3afe92021-05-21 16:20:58 +00001541func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001542 aVersion string) *voltha.ImageState {
1543 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001544 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001545 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001546 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001547 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1548 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1549 if aVersion == dh.pLastUpgradeImageState.Version {
1550 pImageState = dh.pLastUpgradeImageState
1551 } else { //state request for an image version different from last processed image version
1552 pImageState = &voltha.ImageState{
1553 Version: aVersion,
1554 //we cannot state something concerning this version
1555 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1556 Reason: voltha.ImageState_NO_ERROR,
1557 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1558 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001559 }
1560 }
mpagenko38662d02021-08-11 09:45:19 +00001561 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001562}
1563
1564func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1565 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001566 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001567 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001568 dh.lockUpgradeFsm.RLock()
1569 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001570 dh.lockUpgradeFsm.RUnlock()
1571 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001572 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001573 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1574 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1575 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1576 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1577 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1578 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001579 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1580 dh.upgradeCanceled = true
1581 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1582 }
mpagenko45586762021-10-01 08:30:22 +00001583 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001584 } else {
mpagenko45586762021-10-01 08:30:22 +00001585 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001586 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1587 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1588 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1589 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1590 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1591 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001592 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1593 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001594 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1595 //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 +00001596 }
1597}
1598
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001599func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1600
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001601 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001602
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001603 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001604 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001605 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1606 pDevEntry.MutexOnuImageStatus.Lock()
1607 pDevEntry.POnuImageStatus = onuImageStatus
1608 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001609
1610 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001611 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001612 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1613 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001614 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1615 pDevEntry.MutexOnuImageStatus.Lock()
1616 pDevEntry.POnuImageStatus = nil
1617 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001618 return images, err
1619}
1620
Himani Chawla6d2ae152020-09-02 13:11:20 +05301621// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001622// #####################################################################################
1623
1624// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301625// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001626
dbainbri4d3a0dc2020-12-02 00:33:42 +00001627func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001628 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1629 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001630}
1631
1632// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001633func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001634
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001635 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001636 var err error
1637
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001638 // populate what we know. rest comes later after mib sync
1639 dh.device.Root = false
1640 dh.device.Vendor = "OpenONU"
1641 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001642 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001643 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001644
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001645 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001646
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001647 if !dh.IsReconciling() {
1648 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001649 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1650 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1651 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301652 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001653 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001655 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001656 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001657
Himani Chawla4d908332020-08-31 12:30:20 +05301658 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001659 dh.ponPortNumber = dh.device.ParentPortNo
1660
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001661 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1662 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1663 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001664 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001665 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301666 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001667
1668 /*
1669 self._pon = PonPort.create(self, self._pon_port_number)
1670 self._pon.add_peer(self.parent_id, self._pon_port_number)
1671 self.logger.debug('adding-pon-port-to-agent',
1672 type=self._pon.get_port().type,
1673 admin_state=self._pon.get_port().admin_state,
1674 oper_status=self._pon.get_port().oper_status,
1675 )
1676 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001677 if !dh.IsReconciling() {
1678 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001679 var ponPortNo uint32 = 1
1680 if dh.ponPortNumber != 0 {
1681 ponPortNo = dh.ponPortNumber
1682 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001683
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001684 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001685 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001686 PortNo: ponPortNo,
1687 Label: fmt.Sprintf("pon-%d", ponPortNo),
1688 Type: voltha.Port_PON_ONU,
1689 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301690 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001691 PortNo: ponPortNo}}, // Peer port is parent's port number
1692 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001693 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001694 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001695 e.Cancel(err)
1696 return
1697 }
1698 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001699 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001700 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001701 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001702}
1703
1704// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001705func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001706
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001707 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001708 var err error
1709 /*
1710 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1711 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1712 return nil
1713 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001714 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001715 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001716 e.Cancel(err)
1717 return
1718 }
1719
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001720 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001721 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001722 // reconcilement will be continued after mib download is done
1723 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001724
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001725 /*
1726 ############################################################################
1727 # Setup Alarm handler
1728 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1729 device.serial_number)
1730 ############################################################################
1731 # Setup PM configuration for this device
1732 # Pass in ONU specific options
1733 kwargs = {
1734 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1735 'heartbeat': self.heartbeat,
1736 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1737 }
1738 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1739 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1740 self.logical_device_id, device.serial_number,
1741 grouped=True, freq_override=False, **kwargs)
1742 pm_config = self._pm_metrics.make_proto()
1743 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1744 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1745 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1746
1747 # Note, ONU ID and UNI intf set in add_uni_port method
1748 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1749 ani_ports=[self._pon])
1750
1751 # Code to Run OMCI Test Action
1752 kwargs_omci_test_action = {
1753 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1754 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1755 }
1756 serial_number = device.serial_number
1757 self._test_request = OmciTestRequest(self.core_proxy,
1758 self.omci_agent, self.device_id,
1759 AniG, serial_number,
1760 self.logical_device_id,
1761 exclusive=False,
1762 **kwargs_omci_test_action)
1763
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001764 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001765 else:
1766 self.logger.info('onu-already-activated')
1767 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001768
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001769 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001770}
1771
1772// doStateConnected get the device info and update to voltha core
1773// for comparison of the original method (not that easy to uncomment): compare here:
1774// voltha-openolt-adapter/adaptercore/device_handler.go
1775// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001776func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001777
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001778 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301779 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001780 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001781 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001782}
1783
1784// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001785func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001786
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001787 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301788 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001789 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001790 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001791
1792 /*
1793 // Synchronous call to update device state - this method is run in its own go routine
1794 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1795 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001796 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 +00001797 return err
1798 }
1799 return nil
1800 */
1801}
1802
1803// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001804func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001805
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001806 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001807 var err error
1808
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001809 device := dh.device
1810 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001811 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001812 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001813 e.Cancel(err)
1814 return
1815 }
1816
1817 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001818 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001819 /*
1820 // Update the all ports state on that device to disable
1821 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001822 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001823 return er
1824 }
1825
1826 //Update the device oper state and connection status
1827 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1828 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1829 dh.device = cloned
1830
1831 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001832 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001833 return er
1834 }
1835
1836 //get the child device for the parent device
1837 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1838 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001839 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001840 return err
1841 }
1842 for _, onuDevice := range onuDevices.Items {
1843
1844 // Update onu state as down in onu adapter
1845 onuInd := oop.OnuIndication{}
1846 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001847 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001848 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1849 if er != nil {
1850 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001851 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001852 //Do not return here and continue to process other ONUs
1853 }
1854 }
1855 // * Discovered ONUs entries need to be cleared , since after OLT
1856 // is up, it starts sending discovery indications again* /
1857 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001858 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001859 return nil
1860 */
Himani Chawla4d908332020-08-31 12:30:20 +05301861 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001862 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001863 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001864}
1865
Himani Chawla6d2ae152020-09-02 13:11:20 +05301866// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001867// #################################################################################
1868
1869// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301870// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001871
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001872//GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
1873func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001874 dh.lockDevice.RLock()
1875 pOnuDeviceEntry := dh.pOnuOmciDevice
1876 if aWait && pOnuDeviceEntry == nil {
1877 //keep the read sema short to allow for subsequent write
1878 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001879 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001880 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1881 // so it might be needed to wait here for that event with some timeout
1882 select {
1883 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001884 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001885 return nil
1886 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001887 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001888 // if written now, we can return the written value without sema
1889 return dh.pOnuOmciDevice
1890 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001891 }
mpagenko3af1f032020-06-10 08:53:41 +00001892 dh.lockDevice.RUnlock()
1893 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001894}
1895
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001896//setDeviceHandlerEntries sets the ONU device entry within the handler
1897func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1898 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001899 dh.lockDevice.Lock()
1900 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001901 dh.pOnuOmciDevice = apDeviceEntry
1902 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001903 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301904 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001905 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001906}
1907
Himani Chawla6d2ae152020-09-02 13:11:20 +05301908//addOnuDeviceEntry creates a new ONU device or returns the existing
1909func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001910 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001911
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001912 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001913 if deviceEntry == nil {
1914 /* costum_me_map in python code seems always to be None,
1915 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1916 /* also no 'clock' argument - usage open ...*/
1917 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001918 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1919 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1920 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1921 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1922 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001923 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001924 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001925 // fire deviceEntry ready event to spread to possibly waiting processing
1926 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001927 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001928 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001929 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001930 }
1931 // might be updated with some error handling !!!
1932 return nil
1933}
1934
dbainbri4d3a0dc2020-12-02 00:33:42 +00001935func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001936 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001937 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1938
1939 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001940
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001941 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001942 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001943 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1944 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001945 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001946 if !dh.IsReconciling() {
1947 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001948 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001949 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001950 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001951 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001952 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001953
khenaidoo42dcdfd2021-10-19 17:34:12 -04001954 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001955 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001956 OperStatus: voltha.OperStatus_ACTIVATING,
1957 ConnStatus: voltha.ConnectStatus_REACHABLE,
1958 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001959 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001960 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001961 }
1962 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001963 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001964 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001965
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001966 pDevEntry.MutexPersOnuConfig.RLock()
1967 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1968 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001969 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 +00001970 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001971 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001972 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001973 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001974 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001975 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001976 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1977 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1978 // 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 +00001979 // 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 +00001980 // so let's just try to keep it simple ...
1981 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001982 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001983 if err != nil || device == nil {
1984 //TODO: needs to handle error scenarios
1985 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1986 return errors.New("Voltha Device not found")
1987 }
1988 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001989
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001990 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001991 return err
mpagenko3af1f032020-06-10 08:53:41 +00001992 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001993 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001994
1995 /* this might be a good time for Omci Verify message? */
1996 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001997 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001998 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001999 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002000 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002001
2002 /* give the handler some time here to wait for the OMCi verification result
2003 after Timeout start and try MibUpload FSM anyway
2004 (to prevent stopping on just not supported OMCI verification from ONU) */
2005 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002006 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002007 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002008 case testresult := <-verifyExec:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002009 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002010 }
2011
2012 /* In py code it looks earlier (on activate ..)
2013 # Code to Run OMCI Test Action
2014 kwargs_omci_test_action = {
2015 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2016 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2017 }
2018 serial_number = device.serial_number
2019 self._test_request = OmciTestRequest(self.core_proxy,
2020 self.omci_agent, self.device_id,
2021 AniG, serial_number,
2022 self.logical_device_id,
2023 exclusive=False,
2024 **kwargs_omci_test_action)
2025 ...
2026 # Start test requests after a brief pause
2027 if not self._test_request_started:
2028 self._test_request_started = True
2029 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2030 reactor.callLater(tststart, self._test_request.start_collector)
2031
2032 */
2033 /* which is then: in omci_test_request.py : */
2034 /*
2035 def start_collector(self, callback=None):
2036 """
2037 Start the collection loop for an adapter if the frequency > 0
2038
2039 :param callback: (callable) Function to call to collect PM data
2040 """
2041 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2042 if callback is None:
2043 callback = self.perform_test_omci
2044
2045 if self.lc is None:
2046 self.lc = LoopingCall(callback)
2047
2048 if self.default_freq > 0:
2049 self.lc.start(interval=self.default_freq / 10)
2050
2051 def perform_test_omci(self):
2052 """
2053 Perform the initial test request
2054 """
2055 ani_g_entities = self._device.configuration.ani_g_entities
2056 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2057 is not None else None
2058 self._entity_id = ani_g_entities_ids[0]
2059 self.logger.info('perform-test', entity_class=self._entity_class,
2060 entity_id=self._entity_id)
2061 try:
2062 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2063 result = yield self._device.omci_cc.send(frame)
2064 if not result.fields['omci_message'].fields['success_code']:
2065 self.logger.info('Self-Test Submitted Successfully',
2066 code=result.fields[
2067 'omci_message'].fields['success_code'])
2068 else:
2069 raise TestFailure('Test Failure: {}'.format(
2070 result.fields['omci_message'].fields['success_code']))
2071 except TimeoutError as e:
2072 self.deferred.errback(failure.Failure(e))
2073
2074 except Exception as e:
2075 self.logger.exception('perform-test-Error', e=e,
2076 class_id=self._entity_class,
2077 entity_id=self._entity_id)
2078 self.deferred.errback(failure.Failure(e))
2079
2080 */
2081
2082 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002083 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002084
mpagenko1cc3cb42020-07-27 15:24:38 +00002085 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2086 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2087 * 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 +05302088 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002089 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002090 //call MibUploadFSM - transition up to state UlStInSync
2091 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002092 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002093 if pMibUlFsm.Is(mib.UlStDisabled) {
2094 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2095 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2096 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302097 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002098 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302099 //Determine ONU status and start/re-start MIB Synchronization tasks
2100 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002101 if pDevEntry.IsNewOnu() {
2102 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2103 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2104 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002105 }
Himani Chawla4d908332020-08-31 12:30:20 +05302106 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002107 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2108 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2109 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302110 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002111 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002112 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002113 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002114 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002115 "device-id": dh.DeviceID})
2116 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002117 }
2118 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002119 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2120 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002121 }
2122 return nil
2123}
2124
dbainbri4d3a0dc2020-12-02 00:33:42 +00002125func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00002126 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002127 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002128 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
2129 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002130
mpagenko900ee4b2020-10-12 11:56:34 +00002131 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2132 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2133 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002134 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002135 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002136 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002137 // abort: system behavior is just unstable ...
2138 return err
2139 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002140 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002141 _ = 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 +00002142
2143 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002144 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002145 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002146 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002147 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2148 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002149 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002150 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002151
2152 //TODO!!! remove existing traffic profiles
2153 /* from py code, if TP's exist, remove them - not yet implemented
2154 self._tp = dict()
2155 # Let TP download happen again
2156 for uni_id in self._tp_service_specific_task:
2157 self._tp_service_specific_task[uni_id].clear()
2158 for uni_id in self._tech_profile_download_done:
2159 self._tech_profile_download_done[uni_id].clear()
2160 */
2161
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002162 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002163
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002164 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002165
mpagenkoe4782082021-11-25 12:04:26 +00002166 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002167 // abort: system behavior is just unstable ...
2168 return err
2169 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002170 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002171 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002172 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002173 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002174 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2175 OperStatus: voltha.OperStatus_DISCOVERED,
2176 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002177 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002178 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002179 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002180 // abort: system behavior is just unstable ...
2181 return err
2182 }
2183 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002184 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002185 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002186 return nil
2187}
2188
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002189func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002190 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2191 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2192 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2193 // and using the stop/reset event should never harm
2194
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002195 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002196 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002197 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2198 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00002199 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002200 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002201 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002202 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002203 pDevEntry.MutexOnuImageStatus.RLock()
2204 if pDevEntry.POnuImageStatus != nil {
2205 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002206 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002207 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002208
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002209 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002210 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002211 }
2212 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002213 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002214 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002215 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002216 }
mpagenko101ac942021-11-16 15:01:29 +00002217 //stop any deviceHandler reconcile processing (if running)
2218 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002219 //port lock/unlock FSM's may be active
2220 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002221 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002222 }
2223 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002224 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002225 }
2226 //techProfile related PonAniConfigFsm FSM may be active
2227 if dh.pOnuTP != nil {
2228 // should always be the case here
2229 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002230 if dh.pOnuTP.PAniConfigFsm != nil {
2231 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2232 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002233 }
mpagenko900ee4b2020-10-12 11:56:34 +00002234 }
2235 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002236 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002237 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002238 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002239 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002240 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002241 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002242 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002243 } else {
2244 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002245 }
2246 }
2247 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002248 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002249 // Stop collector routine
2250 dh.stopCollector <- true
2251 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002252 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302253 dh.stopAlarmManager <- true
2254 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002255 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002256 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002257 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302258
Girish Gowdrae95687a2021-09-08 16:30:58 -07002259 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2260
mpagenko80622a52021-02-09 16:53:23 +00002261 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002262 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002263 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002264 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002265 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002266 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002267 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002268 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2269 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2270 // (even though it may also run into direct cancellation, a bit hard to verify here)
2271 // so don't set 'dh.upgradeCanceled = true' here!
2272 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2273 }
mpagenko38662d02021-08-11 09:45:19 +00002274 }
mpagenko80622a52021-02-09 16:53:23 +00002275
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002276 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002277 return nil
2278}
2279
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002280func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2281 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 +05302282
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002283 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002284 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002285 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002286 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002287 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002288 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002289 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002290
mpagenkoa40e99a2020-11-17 13:50:39 +00002291 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2292 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2293 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2294 * disable/enable toggling here to allow traffic
2295 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2296 * like the py comment says:
2297 * # start by locking all the unis till mib sync and initial mib is downloaded
2298 * # this way we can capture the port down/up events when we are ready
2299 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302300
mpagenkoa40e99a2020-11-17 13:50:39 +00002301 // Init Uni Ports to Admin locked state
2302 // *** should generate UniLockStateDone event *****
2303 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002304 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002305 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002306 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002307 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002308 }
2309}
2310
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002311func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2312 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302313 /* Mib download procedure -
2314 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2315 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002316 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002317 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002318 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002319 return
2320 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002321 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302322 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002323 if pMibDlFsm.Is(mib.DlStDisabled) {
2324 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2325 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 +05302326 // maybe try a FSM reset and then again ... - TODO!!!
2327 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002328 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302329 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002330 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2331 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302332 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002333 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302334 //Begin MIB data download (running autonomously)
2335 }
2336 }
2337 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002338 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002339 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302340 // maybe try a FSM reset and then again ... - TODO!!!
2341 }
2342 /***** Mib download started */
2343 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002344 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302345 }
2346}
2347
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002348func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2349 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302350 //initiate DevStateUpdate
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002351 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002352 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002353 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002354 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2355 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2356 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2357 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002358 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002359 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002360 ConnStatus: voltha.ConnectStatus_REACHABLE,
2361 OperStatus: voltha.OperStatus_ACTIVE,
2362 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302363 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002364 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302365 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002366 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302367 }
2368 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002369 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002370 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302371 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002372 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002373
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002374 if !dh.GetCollectorIsRunning() {
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002375 // Start PM collector routine
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002376 go dh.StartCollector(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002377 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002378 if !dh.GetAlarmManagerIsRunning(ctx) {
2379 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002380 }
2381
Girish Gowdrae95687a2021-09-08 16:30:58 -07002382 // Start flow handler routines per UNI
2383 for _, uniPort := range dh.uniEntityMap {
2384 // only if this port was enabled for use by the operator at startup
2385 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2386 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2387 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2388 }
2389 }
2390 }
2391
Girish Gowdrae0140f02021-02-02 16:55:09 -08002392 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002393 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002394 // There is no way we should be landing here, but if we do then
2395 // there is nothing much we can do about this other than log error
2396 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2397 }
2398
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002399 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002400
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002401 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002402 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002403 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002404 return
2405 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002406 pDevEntry.MutexPersOnuConfig.RLock()
2407 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2408 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002409 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002410 log.Fields{"device-id": dh.DeviceID})
2411 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002412 // reconcilement will be continued after ani config is done
2413 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002414 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002415 // *** should generate UniUnlockStateDone event *****
2416 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002417 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002418 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002419 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002420 dh.runUniLockFsm(ctx, false)
2421 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302422 }
2423}
2424
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002425func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2426 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302427
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002428 if !dh.IsReconciling() {
2429 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002430 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002431 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2432 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002433 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002434 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002435 return
2436 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002437 pDevEntry.MutexPersOnuConfig.Lock()
2438 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2439 pDevEntry.MutexPersOnuConfig.Unlock()
2440 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002441 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002442 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002443 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302444 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002445 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 +00002446 log.Fields{"device-id": dh.DeviceID})
2447 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002448 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302449 }
2450}
2451
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002452func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002453 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002454 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002455
mpagenko44bd8362021-11-15 11:40:05 +00002456 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002457 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002458 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002459 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002460 OperStatus: voltha.OperStatus_UNKNOWN,
2461 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002462 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002463 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002464 }
2465
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002466 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002467 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002468 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002469
2470 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002471 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002472
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002473 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002474 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002475 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002476 return
2477 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002478 pDevEntry.MutexPersOnuConfig.Lock()
2479 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2480 pDevEntry.MutexPersOnuConfig.Unlock()
2481 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002482 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002483 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002484 }
mpagenko900ee4b2020-10-12 11:56:34 +00002485}
2486
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002487func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002488 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002489 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002490 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002491 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002492 ConnStatus: voltha.ConnectStatus_REACHABLE,
2493 OperStatus: voltha.OperStatus_ACTIVE,
2494 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002495 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002496 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002497 }
2498
dbainbri4d3a0dc2020-12-02 00:33:42 +00002499 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002500 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002501 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002502 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002503
2504 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002505 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002506
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002507 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002508 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002509 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002510 return
2511 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002512 pDevEntry.MutexPersOnuConfig.Lock()
2513 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2514 pDevEntry.MutexPersOnuConfig.Unlock()
2515 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002516 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002517 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002518 }
mpagenko900ee4b2020-10-12 11:56:34 +00002519}
2520
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002521func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2522 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2523 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002524 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002525 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002526 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002527 OperStatus: voltha.OperStatus_FAILED,
2528 }); err != nil {
2529 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2530 }
2531}
2532
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002533func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2534 if devEvent == cmn.OmciAniConfigDone {
2535 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002536 // attention: the device reason update is done based on ONU-UNI-Port related activity
2537 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002538 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002539 // 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 +00002540 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302541 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002542 if dh.IsReconciling() {
2543 go dh.ReconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002544 }
2545 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002546 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002547 // attention: the device reason update is done based on ONU-UNI-Port related activity
2548 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002549 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002550 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
2551 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002552 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002553 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302554}
2555
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002556func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002557 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002558 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302559 // attention: the device reason update is done based on ONU-UNI-Port related activity
2560 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302561
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002562 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2563 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00002564 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00002565 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002566 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002567 if dh.IsReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002568 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002569 }
2570 }
2571 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002572 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002573 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00002574 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002575 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302576 }
mpagenkof1fc3862021-02-16 10:09:52 +00002577
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002578 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002579 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002580 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002581 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002582 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002583 }
2584 } else {
2585 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002586 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002587 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302588}
2589
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002590//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
2591func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302592 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002593 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002594 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002595 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002596 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002597 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002598 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002599 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002600 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002601 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002602 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002603 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002604 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002605 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002606 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002607 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002608 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002609 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002610 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002611 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002612 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002613 case cmn.UniEnableStateFailed:
2614 {
2615 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2616 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002617 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002618 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002619 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002620 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002621 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002622 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002623 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002624 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002625 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002626 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002627 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002628 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002629 default:
2630 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002631 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002632 }
2633 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002634}
2635
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002636func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002637 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002638 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302639 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002640 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002641 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002642 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302643 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002644 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002645 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002646 logger.Warnw(ctx, "OnuUniPort-add: Could not create Port", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002647 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002648 //store UniPort with the System-PortNumber key
2649 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002650 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002651 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002652 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002653 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002654 } //error logging already within UniPort method
2655 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002656 logger.Debugw(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002657 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002658 }
2659 }
2660}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002661
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002662func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2663 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002664 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002665 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002666 return
2667 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002668 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002669 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002670 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2671 for _, mgmtEntityID := range pptpInstKeys {
2672 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002673 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002674 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2675 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002676 }
2677 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002678 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002679 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002680 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002681 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2682 for _, mgmtEntityID := range veipInstKeys {
2683 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002684 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002685 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2686 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002687 }
2688 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002689 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002690 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002691 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002692 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2693 for _, mgmtEntityID := range potsInstKeys {
2694 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002695 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002696 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2697 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002698 }
2699 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002700 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002701 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002702 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002703 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002704 return
2705 }
2706
mpagenko2c3f6c52021-11-23 11:22:10 +00002707 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
2708 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
2709 // 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 -07002710 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2711 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2712 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00002713 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
2714 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002715 for i := 0; i < int(uniCnt); i++ {
2716 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
2717 dh.stopFlowMonitoringRoutine[i] = make(chan bool)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002718 }
2719}
2720
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002721// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2722func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002723 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302724 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002725 // with following remark:
2726 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2727 // # load on the core
2728
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002729 // 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 +00002730
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002731 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002732 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002733 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2734 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2735 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2736 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002737 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002738 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002739 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002740 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002741 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002742 PortNo: port.PortNo,
2743 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002744 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002745 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 -04002746 }
2747 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002748 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002749 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002750 }
mpagenko3af1f032020-06-10 08:53:41 +00002751 }
2752 }
2753}
2754
2755// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002756func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2757 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002758 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2759 for uniNo, uniPort := range dh.uniEntityMap {
2760 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002761
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002762 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2763 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2764 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2765 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002766 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002767 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002768 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002769 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002770 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002771 PortNo: port.PortNo,
2772 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002773 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002774 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 -04002775 }
2776 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002777 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002778 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002779 }
2780
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002781 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002782 }
2783}
2784
2785// ONU_Active/Inactive announcement on system KAFKA bus
2786// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002787func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002788 var de voltha.DeviceEvent
2789 eventContext := make(map[string]string)
2790 //Populating event context
2791 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002792 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002793 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002794 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002795 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002796 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 +00002797 }
2798 oltSerialNumber := parentDevice.SerialNumber
2799
2800 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2801 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2802 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302803 eventContext["olt-serial-number"] = oltSerialNumber
2804 eventContext["device-id"] = aDeviceID
2805 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002806 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002807 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2808 deviceEntry.MutexPersOnuConfig.RLock()
2809 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2810 deviceEntry.MutexPersOnuConfig.RUnlock()
2811 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
2812 deviceEntry.MutexPersOnuConfig.RLock()
2813 eventContext["vendor"] = deviceEntry.SOnuPersistentData.PersVendorID
2814 deviceEntry.MutexPersOnuConfig.RUnlock()
2815 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002816 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2817 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2818 } else {
2819 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2820 log.Fields{"device-id": aDeviceID})
2821 return
2822 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002823
2824 /* Populating device event body */
2825 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302826 de.ResourceId = aDeviceID
2827 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002828 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2829 de.Description = fmt.Sprintf("%s Event - %s - %s",
2830 cEventObjectType, cOnuActivatedEvent, "Raised")
2831 } else {
2832 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2833 de.Description = fmt.Sprintf("%s Event - %s - %s",
2834 cEventObjectType, cOnuActivatedEvent, "Cleared")
2835 }
2836 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002837 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2838 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302839 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002840 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002841 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302842 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002843}
2844
Himani Chawla4d908332020-08-31 12:30:20 +05302845// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002846func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2847 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002848 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302849 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002850 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002851 sFsmName = "LockStateFSM"
2852 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002853 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002854 sFsmName = "UnLockStateFSM"
2855 }
mpagenko3af1f032020-06-10 08:53:41 +00002856
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002857 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002858 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002859 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002860 return
2861 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002862 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002863 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302864 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002865 dh.pLockStateFsm = pLSFsm
2866 } else {
2867 dh.pUnlockStateFsm = pLSFsm
2868 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002869 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002870 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002871 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002872 }
2873}
2874
2875// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002876func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002877 /* Uni Port lock/unlock procedure -
2878 ***** should run via 'adminDone' state and generate the argument requested event *****
2879 */
2880 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302881 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002882 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002883 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2884 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002885 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2886 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002887 }
2888 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002889 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002890 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2891 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002892 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2893 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002894 }
2895 }
2896 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002897 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2898 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002899 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002900 // maybe try a FSM reset and then again ... - TODO!!!
2901 } else {
2902 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002903 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002904 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002905 }
2906 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002907 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002908 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002909 // maybe try a FSM reset and then again ... - TODO!!!
2910 }
2911 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002912 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002913 // maybe try a FSM reset and then again ... - TODO!!!
2914 }
2915}
2916
mpagenko80622a52021-02-09 16:53:23 +00002917// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00002918// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002919func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002920 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002921 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002922 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002923 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002924 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002925 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002926 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002927 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002928 sFsmName, chUpgradeFsm)
2929 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002930 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00002931 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002932 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
2933 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002934 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00002935 // maybe try a FSM reset and then again ... - TODO!!!
2936 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2937 }
mpagenko59862f02021-10-11 08:53:18 +00002938 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00002939 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2940 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00002941 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2942 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002943 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002944 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002945 } else {
2946 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002947 "have": pUpgradeStatemachine.Current(), "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 could not be started for device-id: %s, wrong internal state", dh.device.Id))
2950 }
2951 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002952 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002953 // maybe try a FSM reset and then again ... - TODO!!!
2954 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2955 }
2956 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002957 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002958 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2959 }
2960 return nil
2961}
2962
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002963// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
2964func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002965 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002966 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002967 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00002968 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2969 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00002970 dh.pLastUpgradeImageState = apImageState
2971 dh.lockUpgradeFsm.Unlock()
2972 //signal upgradeFsm removed using non-blocking channel send
2973 select {
2974 case dh.upgradeFsmChan <- struct{}{}:
2975 default:
2976 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002977 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00002978 }
mpagenko80622a52021-02-09 16:53:23 +00002979}
2980
mpagenko15ff4a52021-03-02 10:09:20 +00002981// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2982func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002983 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00002984 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002985 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002986 return
2987 }
2988
2989 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00002990 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00002991 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002992 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
2993 dh.lockUpgradeFsm.RUnlock()
2994 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
2995 return
2996 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002997 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00002998 if pUpgradeStatemachine != nil {
2999 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3000 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003001 UpgradeState := pUpgradeStatemachine.Current()
3002 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3003 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3004 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003005 // 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 +00003006 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003007 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3008 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003009 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003010 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003011 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003012 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3013 dh.upgradeCanceled = true
3014 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3015 }
mpagenko15ff4a52021-03-02 10:09:20 +00003016 return
3017 }
mpagenko59862f02021-10-11 08:53:18 +00003018 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003019 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3020 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003021 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003022 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003023 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3024 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003025 return
3026 }
3027 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003028 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003029 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003030 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3031 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003032 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3033 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003034 return
3035 }
3036 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003037 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003038 }
3039 } else {
3040 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 +00003041 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003042 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3043 dh.upgradeCanceled = true
3044 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3045 }
mpagenko1f8e8822021-06-25 14:10:21 +00003046 }
mpagenko15ff4a52021-03-02 10:09:20 +00003047 return
3048 }
mpagenko59862f02021-10-11 08:53:18 +00003049 dh.lockUpgradeFsm.RUnlock()
3050 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3051 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003052 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3053 dh.upgradeCanceled = true
3054 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3055 }
mpagenko59862f02021-10-11 08:53:18 +00003056 return
3057 }
3058 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3059 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3060 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3061 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3062 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3063 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3064 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003065 }
mpagenko15ff4a52021-03-02 10:09:20 +00003066 }
3067 }
3068 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003069 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003070 }
mpagenko59862f02021-10-11 08:53:18 +00003071 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003072}
3073
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003074//SetBackend provides a DB backend for the specified path on the existing KV client
3075func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003076
3077 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003078 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003079 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003080 kvbackend := &db.Backend{
3081 Client: dh.pOpenOnuAc.kvClient,
3082 StoreType: dh.pOpenOnuAc.KVStoreType,
3083 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003084 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003085 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3086 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003087
mpagenkoaf801632020-07-03 10:00:42 +00003088 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003089}
khenaidoo7d3c5582021-08-11 18:09:44 -04003090func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05303091 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003092
mpagenkodff5dda2020-08-28 11:52:01 +00003093 for _, field := range flow.GetOfbFields(apFlowItem) {
3094 switch field.Type {
3095 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3096 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003097 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003098 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3099 }
mpagenko01e726e2020-10-23 09:45:29 +00003100 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003101 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3102 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303103 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003104 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303105 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3106 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003107 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3108 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003109 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003110 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303111 return
mpagenkodff5dda2020-08-28 11:52:01 +00003112 }
3113 }
mpagenko01e726e2020-10-23 09:45:29 +00003114 */
mpagenkodff5dda2020-08-28 11:52:01 +00003115 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3116 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303117 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003118 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303119 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003120 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303121 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003122 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003123 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303124 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003125 }
3126 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3127 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303128 *loAddPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003129 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003130 "PCP": loAddPcp})
3131 }
3132 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3133 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003134 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003135 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3136 }
3137 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3138 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003139 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003140 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3141 }
3142 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3143 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003144 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003145 "IPv4-DST": field.GetIpv4Dst()})
3146 }
3147 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3148 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003149 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003150 "IPv4-SRC": field.GetIpv4Src()})
3151 }
3152 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3153 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003154 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003155 "Metadata": field.GetTableMetadata()})
3156 }
3157 /*
3158 default:
3159 {
3160 //all other entires ignored
3161 }
3162 */
3163 }
3164 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303165}
mpagenkodff5dda2020-08-28 11:52:01 +00003166
khenaidoo7d3c5582021-08-11 18:09:44 -04003167func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003168 for _, action := range flow.GetActions(apFlowItem) {
3169 switch action.Type {
3170 /* not used:
3171 case of.OfpActionType_OFPAT_OUTPUT:
3172 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003173 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003174 "Output": action.GetOutput()})
3175 }
3176 */
3177 case of.OfpActionType_OFPAT_PUSH_VLAN:
3178 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003179 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003180 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3181 }
3182 case of.OfpActionType_OFPAT_SET_FIELD:
3183 {
3184 pActionSetField := action.GetSetField()
3185 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003186 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003187 "OxcmClass": pActionSetField.Field.OxmClass})
3188 }
3189 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303190 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003191 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303192 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003193 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303194 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003195 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303196 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003197 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003198 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003199 "Type": pActionSetField.Field.GetOfbField().Type})
3200 }
3201 }
3202 /*
3203 default:
3204 {
3205 //all other entires ignored
3206 }
3207 */
3208 }
3209 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303210}
3211
3212//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003213func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003214 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303215 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3216 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
3217 var loAddPcp, loSetPcp uint8
3218 var loIPProto uint32
3219 /* the TechProfileId is part of the flow Metadata - compare also comment within
3220 * OLT-Adapter:openolt_flowmgr.go
3221 * Metadata 8 bytes:
3222 * Most Significant 2 Bytes = Inner VLAN
3223 * Next 2 Bytes = Tech Profile ID(TPID)
3224 * Least Significant 4 Bytes = Port ID
3225 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3226 * subscriber related flows.
3227 */
3228
dbainbri4d3a0dc2020-12-02 00:33:42 +00003229 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303230 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003231 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003232 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003233 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303234 }
mpagenko551a4d42020-12-08 18:09:20 +00003235 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003236 loCookie := apFlowItem.GetCookie()
3237 loCookieSlice := []uint64{loCookie}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003238 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003239 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05303240
dbainbri4d3a0dc2020-12-02 00:33:42 +00003241 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003242 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303243 if loIPProto == 2 {
3244 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3245 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003246 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003247 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303248 return nil
3249 }
mpagenko01e726e2020-10-23 09:45:29 +00003250 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003251 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003252
3253 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003254 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003255 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003256 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3257 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3258 //TODO!!: Use DeviceId within the error response to rwCore
3259 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003260 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003261 }
3262 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003263 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003264 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3265 } else {
3266 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3267 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3268 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303269 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003270 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003271 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003272 }
mpagenko9a304ea2020-12-16 15:54:01 +00003273
khenaidoo42dcdfd2021-10-19 17:34:12 -04003274 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003275 if apFlowMetaData != nil {
3276 meter = apFlowMetaData.Meters[0]
3277 }
mpagenkobc4170a2021-08-17 16:42:10 +00003278 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3279 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3280 // when different rules are requested concurrently for the same uni
3281 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3282 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3283 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003284 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3285 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003286 //SetUniFlowParams() may block on some rule that is suspended-to-add
3287 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003288 // Also the error is returned to caller via response channel
3289 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
3290 loMatchVlan, loSetVlan, loSetPcp, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003291 dh.lockVlanConfig.RUnlock()
3292 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003293 return
mpagenkodff5dda2020-08-28 11:52:01 +00003294 }
mpagenkobc4170a2021-08-17 16:42:10 +00003295 dh.lockVlanConfig.RUnlock()
3296 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003297 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003298 loMatchVlan, loSetVlan, loSetPcp, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003299 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003300 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003301 if err != nil {
3302 *respChan <- err
3303 }
mpagenko01e726e2020-10-23 09:45:29 +00003304}
3305
3306//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003307func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003308 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3309 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3310 //no extra check is done on the rule parameters
3311 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3312 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3313 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3314 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003315 // - 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 +00003316 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003317 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003318
3319 /* TT related temporary workaround - should not be needed anymore
3320 for _, field := range flow.GetOfbFields(apFlowItem) {
3321 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3322 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003323 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003324 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3325 if loIPProto == 2 {
3326 // 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 +00003327 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003328 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003329 return nil
3330 }
3331 }
3332 } //for all OfbFields
3333 */
3334
mpagenko9a304ea2020-12-16 15:54:01 +00003335 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003336 dh.lockVlanConfig.RLock()
3337 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003338 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3339 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003340 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3341 return
mpagenko01e726e2020-10-23 09:45:29 +00003342 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003343 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003344 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003345 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003346 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003347 // Push response on the response channel
3348 if respChan != nil {
3349 // 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
3350 select {
3351 case *respChan <- nil:
3352 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3353 default:
3354 }
3355 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003356 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003357}
3358
Himani Chawla26e555c2020-08-31 12:30:20 +05303359// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003360// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003361// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003362func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003363 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 +00003364 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003365
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003366 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003367 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003368 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3369 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003370 }
3371
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003372 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3373 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003374 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003375 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003376 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3377 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003378 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3379 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003380 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003381 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3382 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003383 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3384 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003385 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003386 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303387 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003388 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003389 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3390 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003391 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003392 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003393 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3394 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003395 }
3396 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003397 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003398 "device-id": dh.DeviceID})
3399 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003400 }
3401 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003402 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003403 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3404 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003405 }
3406 return nil
3407}
3408
mpagenkofc4f56e2020-11-04 17:17:49 +00003409//VerifyVlanConfigRequest checks on existence of a given uniPort
3410// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003411func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003412 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003413 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003414 for _, uniPort := range dh.uniEntityMap {
3415 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003416 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003417 pCurrentUniPort = uniPort
3418 break //found - end search loop
3419 }
3420 }
3421 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003422 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003423 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003424 return
3425 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003426 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003427}
3428
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003429//VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
3430func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003431 //TODO!! verify and start pending flow configuration
3432 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3433 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003434
3435 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003436 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003437 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003438 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003439 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003440 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003441 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003442 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003443 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3444 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003445 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003446 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003447 } else {
3448 /***** UniVlanConfigFsm continued */
3449 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003450 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3451 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003452 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003453 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3454 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003455 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003456 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003457 } else {
3458 /***** UniVlanConfigFsm continued */
3459 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003460 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3461 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003462 }
mpagenkodff5dda2020-08-28 11:52:01 +00003463 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003464 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003465 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3466 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003467 }
3468 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003469 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 +00003470 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3471 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003472 }
3473 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003474 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003475 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003476 }
mpagenkof1fc3862021-02-16 10:09:52 +00003477 } else {
3478 dh.lockVlanConfig.RUnlock()
3479 }
mpagenkodff5dda2020-08-28 11:52:01 +00003480}
3481
3482//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3483// 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 +00003484func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003485 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003486 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003487 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003488 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003489 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003490 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003491}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003492
mpagenkof1fc3862021-02-16 10:09:52 +00003493//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003494func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003495 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3496 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3497 // obviously then parallel processing on the cancel must be avoided
3498 // deadline context to ensure completion of background routines waited for
3499 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3500 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3501 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3502
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003503 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003504 var wg sync.WaitGroup
3505 wg.Add(1) // for the 1 go routine to finish
3506
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003507 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003508 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3509
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003510 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003511}
3512
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003513//StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003514//available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003515func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3516 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003517
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003518 if dh.IsReconciling() {
3519 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003520 return nil
3521 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003522 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003523
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003524 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003525 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003526 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3527 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003528 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003529 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003530
mpagenkof1fc3862021-02-16 10:09:52 +00003531 if aWriteToKvStore {
3532 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3533 }
3534 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003535}
3536
dbainbri4d3a0dc2020-12-02 00:33:42 +00003537func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003538 defer cancel() //ensure termination of context (may be pro forma)
3539 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003540 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003541 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003542}
3543
mpagenkoe4782082021-11-25 12:04:26 +00003544//ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
3545// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
3546func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
3547 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
3548 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
3549 dh.mutexDeviceReason.Lock()
3550 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003551 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003552 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003553 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003554 DeviceId: dh.DeviceID,
3555 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003556 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00003557 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003558 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003559 return err
3560 }
mpagenkoe4782082021-11-25 12:04:26 +00003561 } else {
3562 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 +00003563 }
mpagenkoe4782082021-11-25 12:04:26 +00003564 dh.deviceReason = deviceReason
3565 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
3566 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003567 return nil
3568}
3569
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003570func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3571 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003572 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003573 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3574 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003575 }
mpagenkof1fc3862021-02-16 10:09:52 +00003576 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003577}
3578
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003579// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003580// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003581func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3582 dh.lockDevice.RLock()
3583 defer dh.lockDevice.RUnlock()
3584 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003585 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003586 }
3587 return 0, errors.New("error-fetching-uni-port")
3588}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003589
3590// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003591func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3592 var errorsList []error
3593 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 -08003594
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003595 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3596 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3597 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3598
3599 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3600 // successfully.
3601 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3602 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3603 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003604 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 -08003605 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003606 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003607 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003608 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003609}
3610
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003611func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3612 var err error
3613 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003614 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003615
3616 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003617 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003618 errorsList = append(errorsList, err)
3619 }
3620 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003621 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003622
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003623 return errorsList
3624}
3625
3626func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3627 var err error
3628 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003629 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003630 // Check if group metric related config is updated
3631 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003632 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3633 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3634 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003635
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003636 if ok && m.Frequency != v.GroupFreq {
3637 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003638 errorsList = append(errorsList, err)
3639 }
3640 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003641 if ok && m.Enabled != v.Enabled {
3642 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003643 errorsList = append(errorsList, err)
3644 }
3645 }
3646 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003647 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003648 return errorsList
3649}
3650
3651func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3652 var err error
3653 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003654 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003655 // Check if standalone metric related config is updated
3656 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003657 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3658 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3659 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003660
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003661 if ok && m.Frequency != v.SampleFreq {
3662 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003663 errorsList = append(errorsList, err)
3664 }
3665 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003666 if ok && m.Enabled != v.Enabled {
3667 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003668 errorsList = append(errorsList, err)
3669 }
3670 }
3671 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003672 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003673 return errorsList
3674}
3675
3676// nolint: gocyclo
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003677func (dh *deviceHandler) StartCollector(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003678 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08003679
3680 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003681 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303682 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003683 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003684 // Initialize the next metric collection time.
3685 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3686 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003687 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003688 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003689 for {
3690 select {
3691 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003692 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003693 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003694 // Stop the L2 PM FSM
3695 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003696 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3697 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3698 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003699 }
3700 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003701 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003702 }
3703 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003704 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3705 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003706 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003707 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3708 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003709 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003710
Girish Gowdrae09a6202021-01-12 18:10:59 -08003711 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003712 case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3713 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3714 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3715 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3716 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003717 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003718 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003719 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003720 } else {
3721 if dh.pmConfigs.Grouped { // metrics are managed as a group
3722 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003723 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003724
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003725 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3726 // 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 -08003727 // 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 +00003728 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3729 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003730 }
3731 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003732 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3733 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3734 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3735 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003736 }
3737 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003738 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003739
3740 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003741 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3742 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3743 // 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 -08003744 // 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 +00003745 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3746 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003747 }
3748 }
3749 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003750 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3751 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3752 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3753 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003754 }
3755 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003756 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003757 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003758 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003759 } */
3760 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003761 }
3762 }
3763}
kesavandfdf77632021-01-26 23:40:33 -05003764
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003765func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003766
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003767 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3768 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003769}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003770
Himani Chawla43f95ff2021-06-03 00:24:12 +05303771func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3772 if dh.pOnuMetricsMgr == nil {
3773 return &extension.SingleGetValueResponse{
3774 Response: &extension.GetValueResponse{
3775 Status: extension.GetValueResponse_ERROR,
3776 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3777 },
3778 }
3779 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303780 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303781 return resp
3782}
3783
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003784func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3785 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003786 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003787 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003788 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003789}
3790
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003791func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003792 var pAdapterFsm *cmn.AdapterFsm
3793 //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 +00003794 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003795 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003796 {
mpagenkofbf577d2021-10-12 11:44:33 +00003797 if dh.pOnuOmciDevice != nil {
3798 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
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.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003804 {
mpagenkofbf577d2021-10-12 11:44:33 +00003805 if dh.pOnuOmciDevice != nil {
3806 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
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.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003812 {
mpagenkofbf577d2021-10-12 11:44:33 +00003813 if dh.pLockStateFsm != nil {
3814 pAdapterFsm = dh.pLockStateFsm.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.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003820 {
mpagenkofbf577d2021-10-12 11:44:33 +00003821 if dh.pUnlockStateFsm != nil {
3822 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3823 } else {
3824 return true //FSM not active - so there is no activity on omci
3825 }
mpagenkof1fc3862021-02-16 10:09:52 +00003826 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003827 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003828 {
mpagenkofbf577d2021-10-12 11:44:33 +00003829 if dh.pOnuMetricsMgr != nil {
3830 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003831 } else {
3832 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003833 }
3834 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003835 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003836 {
3837 dh.lockUpgradeFsm.RLock()
3838 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003839 if dh.pOnuUpradeFsm != nil {
3840 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3841 } else {
3842 return true //FSM not active - so there is no activity on omci
3843 }
mpagenko80622a52021-02-09 16:53:23 +00003844 }
mpagenkof1fc3862021-02-16 10:09:52 +00003845 default:
3846 {
3847 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003848 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003849 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003850 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003851 }
mpagenkofbf577d2021-10-12 11:44:33 +00003852 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3853 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3854 }
3855 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003856}
3857
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003858func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3859 for _, v := range dh.pOnuTP.PAniConfigFsm {
3860 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003861 return false
3862 }
3863 }
3864 return true
3865}
3866
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003867func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003868 dh.lockVlanConfig.RLock()
3869 defer dh.lockVlanConfig.RUnlock()
3870 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003871 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003872 return false
3873 }
3874 }
3875 return true //FSM not active - so there is no activity on omci
3876}
3877
3878func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3879 dh.lockVlanConfig.RLock()
3880 defer dh.lockVlanConfig.RUnlock()
3881 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003882 if v.PAdaptFsm.PFsm != nil {
3883 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003884 return true //there is at least one VLAN FSM with some active configuration
3885 }
3886 }
3887 }
3888 return false //there is no VLAN FSM with some active configuration
3889}
3890
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003891func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003892 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3893 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3894 return false
3895 }
3896 }
3897 // a further check is done to identify, if at least some data traffic related configuration exists
3898 // 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])
3899 return dh.checkUserServiceExists(ctx)
3900}
3901
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003902func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003903 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3904 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003905 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003906 // TODO: fatal error reset ONU, delete deviceHandler!
3907 return
3908 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003909 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
3910 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003911}
3912
3913func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3914 dh.mutexCollectorFlag.Lock()
3915 dh.collectorIsRunning = flagValue
3916 dh.mutexCollectorFlag.Unlock()
3917}
3918
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003919func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003920 dh.mutexCollectorFlag.RLock()
3921 flagValue := dh.collectorIsRunning
3922 dh.mutexCollectorFlag.RUnlock()
3923 return flagValue
3924}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303925
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303926func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3927 dh.mutextAlarmManagerFlag.Lock()
3928 dh.alarmManagerIsRunning = flagValue
3929 dh.mutextAlarmManagerFlag.Unlock()
3930}
3931
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003932func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303933 dh.mutextAlarmManagerFlag.RLock()
3934 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003935 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303936 dh.mutextAlarmManagerFlag.RUnlock()
3937 return flagValue
3938}
3939
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003940func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003941 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303942
3943 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003944 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303945 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303946 if stop := <-dh.stopAlarmManager; stop {
3947 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303948 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303949 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003950 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
3951 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05303952 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303953 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003954 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
3955 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05303956 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303957 }
3958}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003959
Girish Gowdrae95687a2021-09-08 16:30:58 -07003960func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
3961 dh.mutexFlowMonitoringRoutineFlag.Lock()
3962 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003963 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003964 dh.isFlowMonitoringRoutineActive[uniID] = flag
3965}
3966
3967func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
3968 dh.mutexFlowMonitoringRoutineFlag.RLock()
3969 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
3970 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003971 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003972 return dh.isFlowMonitoringRoutineActive[uniID]
3973}
3974
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003975func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
3976 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003977
Maninder7961d722021-06-16 22:10:28 +05303978 connectStatus := voltha.ConnectStatus_UNREACHABLE
3979 operState := voltha.OperStatus_UNKNOWN
3980
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003981 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003982 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003983 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00003984 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003985 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003986 case success := <-dh.chReconcilingFinished:
3987 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003988 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05303989 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003990 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05303991 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00003992 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003993 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05303994 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003995 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
3996 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05303997 operState = voltha.OperStatus_ACTIVE
3998 } else {
3999 operState = voltha.OperStatus_ACTIVATING
4000 }
4001 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004002 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4003 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4004 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304005 operState = voltha.OperStatus_DISCOVERED
4006 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004007 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004008 logger.Debugw(ctx, "Core DeviceStateUpdate",
4009 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304010 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004011 logger.Debugw(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004012 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004013 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004014 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004015 ConnStatus: connectStatus,
4016 OperStatus: operState,
4017 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304018 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004019 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304020 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004021 } else {
Maninderb5187552021-03-23 22:23:42 +05304022 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004023 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304024
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004025 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304026 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004027 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004028 } else {
4029 onuDevEntry.MutexPersOnuConfig.RLock()
4030 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4031 connectStatus = voltha.ConnectStatus_REACHABLE
4032 }
4033 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304034 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004035 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004036 }
mpagenko101ac942021-11-16 15:01:29 +00004037 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004038 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004039 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304040
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004041 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304042 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004043 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004044 } else {
4045 onuDevEntry.MutexPersOnuConfig.RLock()
4046 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4047 connectStatus = voltha.ConnectStatus_REACHABLE
4048 }
4049 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304050 }
4051
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004052 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304053
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004054 }
4055 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004056 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004057 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004058 dh.SetReconcilingReasonUpdate(false)
4059
4060 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4061 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4062 } else {
4063 onuDevEntry.MutexReconciledTpInstances.Lock()
4064 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
4065 onuDevEntry.MutexReconciledTpInstances.Unlock()
4066 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004067 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004068 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004069 dh.mutexReconcilingFlag.Lock()
4070 if skipOnuConfig {
4071 dh.reconciling = cSkipOnuConfigReconciling
4072 } else {
4073 dh.reconciling = cOnuConfigReconciling
4074 }
4075 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004076}
4077
mpagenko101ac942021-11-16 15:01:29 +00004078func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004079 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
4080 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004081 dh.sendChReconcileFinished(success)
4082 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4083 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4084 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004085 } else {
mpagenko101ac942021-11-16 15:01:29 +00004086 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004087 }
4088}
4089
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004090func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004091 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004092 defer dh.mutexReconcilingFlag.RUnlock()
4093 return dh.reconciling != cNoReconciling
4094}
4095
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004096func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004097 dh.mutexReconcilingFlag.RLock()
4098 defer dh.mutexReconcilingFlag.RUnlock()
4099 return dh.reconciling == cSkipOnuConfigReconciling
4100}
4101
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004102func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4103 dh.mutexReconcilingReasonUpdate.Lock()
4104 dh.reconcilingReasonUpdate = value
4105 dh.mutexReconcilingReasonUpdate.Unlock()
4106}
4107
4108func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4109 dh.mutexReconcilingReasonUpdate.RLock()
4110 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4111 return dh.reconcilingReasonUpdate
4112}
4113
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004114func (dh *deviceHandler) getDeviceReason() uint8 {
4115 dh.mutexDeviceReason.RLock()
4116 value := dh.deviceReason
4117 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004118 return value
4119}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004120
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004121func (dh *deviceHandler) GetDeviceReasonString() string {
4122 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004123}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004124
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004125func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004126 dh.mutexReadyForOmciConfig.Lock()
4127 dh.readyForOmciConfig = flagValue
4128 dh.mutexReadyForOmciConfig.Unlock()
4129}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004130func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004131 dh.mutexReadyForOmciConfig.RLock()
4132 flagValue := dh.readyForOmciConfig
4133 dh.mutexReadyForOmciConfig.RUnlock()
4134 return flagValue
4135}
Maninder7961d722021-06-16 22:10:28 +05304136
4137func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004138 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304139 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004140 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304141 }
4142
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004143 logger.Debugw(ctx, "Core DeviceStateUpdate",
4144 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004145 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004146 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004147 ConnStatus: connectStatus,
4148 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4149 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304150 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004151 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304152 }
4153}
khenaidoo7d3c5582021-08-11 18:09:44 -04004154
4155/*
4156Helper functions to communicate with Core
4157*/
4158
4159func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4160 cClient, err := dh.coreClient.GetCoreServiceClient()
4161 if err != nil || cClient == nil {
4162 return nil, err
4163 }
4164 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4165 defer cancel()
4166 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4167 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4168}
4169
khenaidoo42dcdfd2021-10-19 17:34:12 -04004170func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004171 cClient, err := dh.coreClient.GetCoreServiceClient()
4172 if err != nil || cClient == nil {
4173 return err
4174 }
4175 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4176 defer cancel()
4177 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004178 logger.Debugw(subCtx, "device-updated-in-core",
4179 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004180 return err
4181}
4182
4183func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4184 cClient, err := dh.coreClient.GetCoreServiceClient()
4185 if err != nil || cClient == nil {
4186 return err
4187 }
4188 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4189 defer cancel()
4190 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004191 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4192 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004193 return err
4194}
4195
4196func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4197 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.DeviceUpdate(subCtx, device)
4204 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4205 return err
4206}
4207
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004208func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) 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.PortCreated(subCtx, port)
4216 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4217 return err
4218}
4219
khenaidoo42dcdfd2021-10-19 17:34:12 -04004220func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) 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.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004228 logger.Debugw(subCtx, "port-state-updated-in-core", log.Fields{"device-id": dh.device.Id, "port-state": portState, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004229 return err
4230}
4231
khenaidoo42dcdfd2021-10-19 17:34:12 -04004232func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004233 cClient, err := dh.coreClient.GetCoreServiceClient()
4234 if err != nil || cClient == nil {
4235 return err
4236 }
4237 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4238 defer cancel()
4239 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004240 logger.Debugw(subCtx, "device-reason-updated-in-core", log.Fields{"device-id": dh.device.Id, "reason": reason, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004241 return err
4242}
4243
4244/*
4245Helper functions to communicate with parent adapter
4246*/
4247
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004248func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4249 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4250
4251 var request = ia.TechProfileInstanceRequestMessage{
4252 DeviceId: dh.DeviceID,
4253 TpInstancePath: aTpPath,
4254 ParentDeviceId: dh.parentID,
4255 ParentPonPort: dh.device.ParentPortNo,
4256 OnuId: dh.device.ProxyAddress.OnuId,
4257 UniId: uint32(aUniID),
4258 }
4259
4260 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004261 if err != nil || pgClient == nil {
4262 return nil, err
4263 }
4264 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4265 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004266 logger.Debugw(subCtx, "get-tech-profile-instance",
4267 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004268 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004269}
4270
Girish Gowdrae95687a2021-09-08 16:30:58 -07004271// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4272// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4273func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4274 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4275 dh.setFlowMonitoringIsRunning(uniID, true)
4276 for {
4277 select {
4278 // block on the channel to receive an incoming flow
4279 // process the flow completely before proceeding to handle the next flow
4280 case flowCb := <-dh.flowCbChan[uniID]:
4281 startTime := time.Now()
4282 logger.Debugw(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
4283 respChan := make(chan error)
4284 if flowCb.addFlow {
4285 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4286 } else {
4287 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4288 }
4289 // Block on response and tunnel it back to the caller
4290 *flowCb.respChan <- <-respChan
4291 logger.Debugw(flowCb.ctx, "serial-flow-processor--end",
4292 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4293 case <-dh.stopFlowMonitoringRoutine[uniID]:
4294 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4295 dh.setFlowMonitoringIsRunning(uniID, false)
4296 return
4297 }
4298 }
4299}
4300
khenaidoo42dcdfd2021-10-19 17:34:12 -04004301func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004302 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4303 if err != nil || pgClient == nil {
4304 return err
4305 }
4306 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4307 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004308 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004309 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4310 if err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004311 logger.Errorw(ctx, "omci-failure",
4312 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
4313 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
khenaidoo7d3c5582021-08-11 18:09:44 -04004314 }
4315 return err
4316}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004317
4318// GetDeviceID - TODO: add comment
4319func (dh *deviceHandler) GetDeviceID() string {
4320 return dh.DeviceID
4321}
4322
4323// GetProxyAddressID - TODO: add comment
4324func (dh *deviceHandler) GetProxyAddressID() string {
4325 return dh.device.ProxyAddress.GetDeviceId()
4326}
4327
4328// GetProxyAddressType - TODO: add comment
4329func (dh *deviceHandler) GetProxyAddressType() string {
4330 return dh.device.ProxyAddress.GetDeviceType()
4331}
4332
4333// GetProxyAddress - TODO: add comment
4334func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4335 return dh.device.ProxyAddress
4336}
4337
4338// GetEventProxy - TODO: add comment
4339func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4340 return dh.EventProxy
4341}
4342
4343// GetOmciTimeout - TODO: add comment
4344func (dh *deviceHandler) GetOmciTimeout() int {
4345 return dh.pOpenOnuAc.omciTimeout
4346}
4347
4348// GetAlarmAuditInterval - TODO: add comment
4349func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4350 return dh.pOpenOnuAc.alarmAuditInterval
4351}
4352
4353// GetDlToOnuTimeout4M - TODO: add comment
4354func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4355 return dh.pOpenOnuAc.dlToOnuTimeout4M
4356}
4357
4358// GetUniEntityMap - TODO: add comment
4359func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4360 return &dh.uniEntityMap
4361}
4362
4363// GetPonPortNumber - TODO: add comment
4364func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4365 return &dh.ponPortNumber
4366}
4367
4368// GetUniVlanConfigFsm - TODO: add comment
4369func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004370 dh.lockVlanConfig.RLock()
4371 value := dh.UniVlanConfigFsmMap[uniID]
4372 dh.lockVlanConfig.RUnlock()
4373 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004374}
4375
4376// GetOnuAlarmManager - TODO: add comment
4377func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4378 return dh.pAlarmMgr
4379}
4380
4381// GetOnuMetricsManager - TODO: add comment
4382func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4383 return dh.pOnuMetricsMgr
4384}
4385
4386// GetOnuTP - TODO: add comment
4387func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4388 return dh.pOnuTP
4389}
4390
4391// GetBackendPathPrefix - TODO: add comment
4392func (dh *deviceHandler) GetBackendPathPrefix() string {
4393 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4394}
4395
4396// GetOnuIndication - TODO: add comment
4397func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4398 return dh.pOnuIndication
4399}
4400
4401// RLockMutexDeletionInProgressFlag - TODO: add comment
4402func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4403 dh.mutexDeletionInProgressFlag.RLock()
4404}
4405
4406// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4407func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4408 dh.mutexDeletionInProgressFlag.RUnlock()
4409}
4410
4411// GetDeletionInProgress - TODO: add comment
4412func (dh *deviceHandler) GetDeletionInProgress() bool {
4413 return dh.deletionInProgress
4414}
4415
4416// GetPmConfigs - TODO: add comment
4417func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4418 return dh.pmConfigs
4419}
4420
4421// GetDeviceType - TODO: add comment
4422func (dh *deviceHandler) GetDeviceType() string {
4423 return dh.DeviceType
4424}
4425
4426// GetLogicalDeviceID - TODO: add comment
4427func (dh *deviceHandler) GetLogicalDeviceID() string {
4428 return dh.logicalDeviceID
4429}
4430
4431// GetDevice - TODO: add comment
4432func (dh *deviceHandler) GetDevice() *voltha.Device {
4433 return dh.device
4434}
4435
4436// GetMetricsEnabled - TODO: add comment
4437func (dh *deviceHandler) GetMetricsEnabled() bool {
4438 return dh.pOpenOnuAc.MetricsEnabled
4439}
4440
4441// InitPmConfigs - TODO: add comment
4442func (dh *deviceHandler) InitPmConfigs() {
4443 dh.pmConfigs = &voltha.PmConfigs{}
4444}
4445
4446// GetUniPortMask - TODO: add comment
4447func (dh *deviceHandler) GetUniPortMask() int {
4448 return dh.pOpenOnuAc.config.UniPortMask
4449}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00004450
4451func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
4452 tpPathFound := false
4453 for _, tpPath := range aTpPathMap {
4454 if tpPath != "" {
4455 tpPathFound = true
4456 }
4457 }
4458 return tpPathFound
4459}