blob: 332861b3f320eb16af8d86797bc557f513af15a2 [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 Hildebrandt7741f272022-01-18 08:17:39 +0000208 reconcilingFirstPass bool
209 mutexReconcilingFirstPassFlag sync.RWMutex
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000210 reconcilingReasonUpdate bool
211 mutexReconcilingReasonUpdate sync.RWMutex
mpagenko101ac942021-11-16 15:01:29 +0000212 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
213 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
214 reconcileExpiryComplete time.Duration
215 reconcileExpiryVlanConfig time.Duration
216 mutexReadyForOmciConfig sync.RWMutex
217 readyForOmciConfig bool
218 deletionInProgress bool
219 mutexDeletionInProgressFlag sync.RWMutex
220 pLastUpgradeImageState *voltha.ImageState
221 upgradeFsmChan chan struct{}
Girish Gowdrae95687a2021-09-08 16:30:58 -0700222
223 flowCbChan []chan FlowCb
224 mutexFlowMonitoringRoutineFlag sync.RWMutex
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300225 mutexForDisableDeviceRequested sync.RWMutex
Girish Gowdrae95687a2021-09-08 16:30:58 -0700226 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
227 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300228 disableDeviceRequested bool // this flag identify ONU received disable request or not
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000229}
230
Himani Chawla6d2ae152020-09-02 13:11:20 +0530231//newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400232func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530233 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400234 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000235 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400236 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000237 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000238 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000239 dh.DeviceType = cloned.Type
240 dh.adminState = "up"
241 dh.device = cloned
242 dh.pOpenOnuAc = adapter
243 dh.exitChannel = make(chan int, 1)
244 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000245 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000246 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000247 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530248 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530249 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000250 dh.stopHeartbeatCheck = make(chan bool, 2)
251 //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 +0000252 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000253 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000254 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000255 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000256 dh.lockUpgradeFsm = sync.RWMutex{}
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300257 dh.mutexForDisableDeviceRequested = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000258 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000259 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000260 dh.reconcilingReasonUpdate = false
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000261 dh.reconcilingFirstPass = true
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300262 dh.disableDeviceRequested = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000263 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000264 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
265 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
266 if rECSeconds < 2 {
267 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
268 rECSeconds = 2
269 }
270 rEVCSeconds := rECSeconds / 2
271 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000272 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000273 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000274 dh.pLastUpgradeImageState = &voltha.ImageState{
275 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
276 Reason: voltha.ImageState_UNKNOWN_ERROR,
277 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
278 }
279 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000280
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800281 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
282 dh.pmConfigs = cloned.PmConfigs
283 } /* else {
284 // will be populated when onu_metrics_mananger is initialized.
285 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800286
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000287 // Device related state machine
288 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000289 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000290 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000291 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
292 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
293 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
294 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
295 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000296 },
297 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000298 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
299 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
300 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
301 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
302 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
303 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
304 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
305 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000306 },
307 )
mpagenkoaf801632020-07-03 10:00:42 +0000308
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000309 return &dh
310}
311
Himani Chawla6d2ae152020-09-02 13:11:20 +0530312// start save the device to the data model
313func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000314 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000315 // Add the initial device to the local model
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000316 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000317}
318
Himani Chawla4d908332020-08-31 12:30:20 +0530319/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000320// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530321func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000322 logger.Debug("stopping-device-handler")
323 dh.exitChannel <- 1
324}
Himani Chawla4d908332020-08-31 12:30:20 +0530325*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000326
327// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530328// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000329
Girish Gowdrae0140f02021-02-02 16:55:09 -0800330//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530331func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400332 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000333
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000334 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000335 if dh.pDeviceStateFsm.Is(devStNull) {
336 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000337 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 +0000338 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000339 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800340 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
341 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800342 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400343 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000344 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800345 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800346 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000347 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000348 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000349 }
350
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000351}
352
khenaidoo42dcdfd2021-10-19 17:34:12 -0400353func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000354 /* 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 +0530355 //assuming omci message content is hex coded!
356 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000357 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000358 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000359 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000360 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530361 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000362 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000363 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000364 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000365 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
366 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530367 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000368 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
369 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530370}
371
khenaidoo42dcdfd2021-10-19 17:34:12 -0400372func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000373 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000374
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000375 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000376 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000377 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
378 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000379 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530380 if dh.pOnuTP == nil {
381 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000382 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000383 log.Fields{"device-id": dh.DeviceID})
384 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530385 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000386 if !dh.IsReadyForOmciConfig() {
387 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
388 "device-state": dh.GetDeviceReasonString()})
389 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530390 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000391 //previous state test here was just this one, now extended for more states to reject the SetRequest:
392 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
393 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530394
Himani Chawla26e555c2020-08-31 12:30:20 +0530395 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000396 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
397 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000398 dh.pOnuTP.LockTpProcMutex()
399 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000400
mpagenko44bd8362021-11-15 11:40:05 +0000401 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000402 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000403 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000404 }
405 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000406 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800407 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700408 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800409 return err
410 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000411 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
412 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000413
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000414 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530415
Girish Gowdra50e56422021-06-01 16:46:04 -0700416 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400417 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000418 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
419 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700420 // if there has been some change for some uni TechProfilePath
421 //in order to allow concurrent calls to other dh instances we do not wait for execution here
422 //but doing so we can not indicate problems to the caller (who does what with that then?)
423 //by now we just assume straightforward successful execution
424 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
425 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530426
Girish Gowdra50e56422021-06-01 16:46:04 -0700427 // deadline context to ensure completion of background routines waited for
428 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
429 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
430 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000431
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000432 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700433
434 var wg sync.WaitGroup
435 wg.Add(1) // for the 1 go routine to finish
436 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000437 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700438 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000439 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
440 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 -0700441 return tpErr
442 }
443 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
444 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000445 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700446 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000447 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700448 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000449 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
450 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 -0700451 return kvErr
452 }
453 return nil
454 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000455 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700456 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700457 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530458 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000459 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000460 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
461 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530462 return nil
463}
464
khenaidoo42dcdfd2021-10-19 17:34:12 -0400465func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000466 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530467
468 if dh.pOnuTP == nil {
469 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000470 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000471 log.Fields{"device-id": dh.DeviceID})
472 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530473 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530474 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000475 dh.pOnuTP.LockTpProcMutex()
476 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530477
mpagenko0f543222021-11-03 16:24:14 +0000478 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
479 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
480 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000481 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000482 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000483 }
484 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000485 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800486 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000487 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
488 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800489 return err
490 }
mpagenko0f543222021-11-03 16:24:14 +0000491 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
492 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000493 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000494
Mahir Gunyel9545be22021-07-04 15:53:16 -0700495 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000496 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000497
Himani Chawla26e555c2020-08-31 12:30:20 +0530498}
499
khenaidoo42dcdfd2021-10-19 17:34:12 -0400500func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000501 logger.Infow(ctx, "delete-tcont-request start", log.Fields{"device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId, "tcont": delTcontMsg.AllocId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000502
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000503 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000504 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000505 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
506 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000507 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530508 if dh.pOnuTP == nil {
509 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000510 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000511 log.Fields{"device-id": dh.DeviceID})
512 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530513 }
514
Himani Chawla26e555c2020-08-31 12:30:20 +0530515 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000516 dh.pOnuTP.LockTpProcMutex()
517 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000518
mpagenko0f543222021-11-03 16:24:14 +0000519 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
520 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
521 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000522 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000523 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000524 }
525 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700526 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000527 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800528 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000529 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
530 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800531 return err
532 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000533 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530534
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000535 var wg sync.WaitGroup
536 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
537 dctx, cancel := context.WithDeadline(context.Background(), deadline)
538 wg.Add(1)
539 logger.Debugw(ctx, "remove-tcont-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "tcont": delTcontMsg.AllocId})
540 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
541 dh.waitForCompletion(ctx, cancel, &wg, "DeleteTcont") //wait for background process to finish
542 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
543 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
544 return err
545 }
546
Mahir Gunyel9545be22021-07-04 15:53:16 -0700547 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000548 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000549
Mahir Gunyel9545be22021-07-04 15:53:16 -0700550}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000551
Mahir Gunyel9545be22021-07-04 15:53:16 -0700552func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000553 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
554 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700555 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000556 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
557 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530558 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700559 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000560 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700561 resourceName = "Gem"
562 } else {
563 resourceName = "Tcont"
564 }
565
566 // deadline context to ensure completion of background routines waited for
567 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
568 dctx, cancel := context.WithDeadline(context.Background(), deadline)
569
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000570 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700571
572 var wg sync.WaitGroup
573 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000574 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700575 resource, entryID, &wg)
576 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000577 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
578 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700579 return err
580 }
581
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000582 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
583 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
584 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
585 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700586 var wg2 sync.WaitGroup
587 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
588 wg2.Add(1)
589 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000590 logger.Debugw(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000591 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700592 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000593 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
594 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700595 return err
596 }
597 }
598 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000599 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700600 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530601 return nil
602}
603
mpagenkodff5dda2020-08-28 11:52:01 +0000604//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000605func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400606 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400607 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700608 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
609 var errorsList []error
610 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000611 //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 +0000612 if apOfFlowChanges.ToRemove != nil {
613 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000614 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000615 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000616 "device-id": dh.DeviceID})
617 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700618 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000619 continue
620 }
621 flowInPort := flow.GetInPort(flowItem)
622 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000623 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
624 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700625 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000626 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000627 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000628 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000629 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000630 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000631 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000632 continue
633 } else {
634 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000635 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000636 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
637 loUniPort = uniPort
638 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000639 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000640 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000641 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000642 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700643 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000644 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000645 }
646 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000647 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000648 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
649 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700650
651 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
652 // Step1 : Fill flowControlBlock
653 // Step2 : Push the flowControlBlock to ONU channel
654 // Step3 : Wait on response channel for response
655 // Step4 : Return error value
656 startTime := time.Now()
657 respChan := make(chan error)
658 flowCb := FlowCb{
659 ctx: ctx,
660 addFlow: false,
661 flowItem: flowItem,
662 flowMetaData: nil,
663 uniPort: loUniPort,
664 respChan: &respChan,
665 }
666 dh.flowCbChan[loUniPort.UniID] <- flowCb
667 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
668 // Wait on the channel for flow handlers return value
669 retError = <-respChan
670 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
671 if retError != nil {
672 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
673 log.Fields{"device-id": dh.DeviceID, "error": retError})
674 errorsList = append(errorsList, retError)
675 continue
676 }
677 } else {
678 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
679 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000680 }
681 }
682 }
683 }
mpagenko01e726e2020-10-23 09:45:29 +0000684 if apOfFlowChanges.ToAdd != nil {
685 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
686 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000687 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000688 "device-id": dh.DeviceID})
689 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700690 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000691 continue
692 }
693 flowInPort := flow.GetInPort(flowItem)
694 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000695 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
696 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700697 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000698 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000699 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000700 } else if flowInPort == dh.ponPortNumber {
701 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000702 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000703 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000704 continue
705 } else {
706 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000707 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000708 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
709 loUniPort = uniPort
710 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000711 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000712 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000713 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000714 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700715 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000716 continue
mpagenko01e726e2020-10-23 09:45:29 +0000717 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000718 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
719 // if not, we just throw some error here to have an indication about that, if we really need to support that
720 // then we would need to create some means to activate the internal stored flows
721 // after the device gets active automatically (and still with its dependency to the TechProfile)
722 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
723 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000724 if !dh.IsReadyForOmciConfig() {
725 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
726 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700727 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
728 errorsList = append(errorsList, retError)
729 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000730 }
731
mpagenko01e726e2020-10-23 09:45:29 +0000732 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000733 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000734 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
735 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700736 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
737 // Step1 : Fill flowControlBlock
738 // Step2 : Push the flowControlBlock to ONU channel
739 // Step3 : Wait on response channel for response
740 // Step4 : Return error value
741 startTime := time.Now()
742 respChan := make(chan error)
743 flowCb := FlowCb{
744 ctx: ctx,
745 addFlow: true,
746 flowItem: flowItem,
747 flowMetaData: apFlowMetaData,
748 uniPort: loUniPort,
749 respChan: &respChan,
750 }
751 dh.flowCbChan[loUniPort.UniID] <- flowCb
752 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
753 // Wait on the channel for flow handlers return value
754 retError = <-respChan
755 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
756 if retError != nil {
757 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
758 log.Fields{"device-id": dh.DeviceID, "error": retError})
759 errorsList = append(errorsList, retError)
760 continue
761 }
762 } else {
763 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
764 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000765 }
766 }
767 }
768 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700769 if len(errorsList) > 0 {
770 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
771 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
772 }
773 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000774}
775
Himani Chawla6d2ae152020-09-02 13:11:20 +0530776//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000777//following are the expected device states after this activity:
778//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
779// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000780func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
781 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300782 dh.mutexForDisableDeviceRequested.Lock()
783 dh.disableDeviceRequested = true
784 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000785 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000786 //note that disableDevice sequences in some 'ONU active' state may yield also
787 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000788 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000789 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000790 //disable-device shall be just a UNi/ONU-G related admin state setting
791 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000792
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000793 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000794 // disable UNI ports/ONU
795 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
796 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000797 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000798 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000799 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000800 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000801 }
802 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000803 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000804 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000805 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400806 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000807 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000808 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400809 OperStatus: voltha.OperStatus_UNKNOWN,
810 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000811 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000812 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000813 }
mpagenko01e726e2020-10-23 09:45:29 +0000814 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000815
816 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000817 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000818 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300819 }
820}
821
Himani Chawla6d2ae152020-09-02 13:11:20 +0530822//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000823func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
824 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000825
mpagenkoaa3afe92021-05-21 16:20:58 +0000826 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000827 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
828 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
829 // for real ONU's that should have nearly no influence
830 // Note that for real ONU's there is anyway a problematic situation with following sequence:
831 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
832 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
833 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000834 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000835
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000836 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000837 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300838 dh.mutexForDisableDeviceRequested.Lock()
839 dh.disableDeviceRequested = false
840 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000841 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000842 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000843 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000844 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000845 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000846 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300847}
848
dbainbri4d3a0dc2020-12-02 00:33:42 +0000849func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000850 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000851
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000852 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000853 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000854 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000855 return
856 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000857 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000858 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000859 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000860 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000861 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000862 }
mpagenko101ac942021-11-16 15:01:29 +0000863 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000864 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000865 }
Himani Chawla4d908332020-08-31 12:30:20 +0530866 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000867 pDevEntry.MutexPersOnuConfig.RLock()
868 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
869 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
870 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
871 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
872 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000873 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000874}
875
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000876func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000877 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000878
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000879 continueWithFlowConfig := false
880
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000881 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000882 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000883 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000884 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
885 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000886 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000887 dh.pOnuTP.LockTpProcMutex()
888 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000889
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000890 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000891 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000892 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
893 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000894 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000895 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000896 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
897 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000898 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000899 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700900 techProfsFound := false
901 techProfInstLoadFailed := false
902outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000903 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000904 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000905 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000906 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000907 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000908 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000909 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000910 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000911 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
912 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000913 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000914 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000915 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700916 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000917 var iaTechTpInst ia.TechProfileDownloadMessage
918 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800919 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000920 pDevEntry.MutexReconciledTpInstances.RLock()
921 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
922 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000923 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000924 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700925 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000926 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700927 break outerLoop
928 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000929 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000930 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700931 var tpInst tech_profile.TechProfileInstance
932 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400933 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700934 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000935 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000936 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700937 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000938 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000939 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700940 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
941 break outerLoop
942 }
943
Girish Gowdra041dcb32020-11-16 16:54:30 -0800944 // deadline context to ensure completion of background routines waited for
945 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
946 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000947 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000948
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000949 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800950 var wg sync.WaitGroup
951 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000952 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000953 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000954 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
955 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700956 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
957 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800958 }
mpagenko2dc896e2021-08-02 12:03:59 +0000959 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000960 if len(uniData.PersFlowParams) != 0 {
961 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000962 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000963 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000964 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000965 } // for all UNI entries from SOnuPersistentData
966 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
967 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000968 }
mpagenko2dc896e2021-08-02 12:03:59 +0000969
970 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
971 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000972
973 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +0000974}
975
976func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
977 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
978 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000979 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000980 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000981 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000982 return
983 }
mpagenko2dc896e2021-08-02 12:03:59 +0000984 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000985 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +0000986 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -0700987 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000988 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000989 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000990 }
mpagenko2dc896e2021-08-02 12:03:59 +0000991 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000992 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000993 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000994 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000995 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000996}
997
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000998func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
999 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001000
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001001 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001002 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001003 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001004 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001005 return
1006 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001007
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001008 pDevEntry.MutexPersOnuConfig.RLock()
1009 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1010 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001011 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001012 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001013 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001014 return
1015 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001016 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001017 var uniVlanConfigEntries []uint8
1018 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1019
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001020 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001021 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1022 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001023 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001024 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001025 continue
1026 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001027 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001028 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001029 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001030 // It doesn't make sense to configure any flows if no TPs are available
1031 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001032 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001033 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1034 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001035 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001036 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001037
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001038 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001039 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001040 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001041 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001042 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1043 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001044 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001045 return
1046 }
mpagenko101ac942021-11-16 15:01:29 +00001047 //needed to split up function due to sca complexity
1048 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1049
mpagenko2dc896e2021-08-02 12:03:59 +00001050 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001051 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001052 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1053 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001054 // this can't be used as global finished reconciling flag because
1055 // assumes is getting called before the state machines for the last flow is completed,
1056 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001057 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1058 } // for all UNI entries from SOnuPersistentData
1059 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001060
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001061 if !flowsFound {
1062 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001063 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001064 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001065 return
1066 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001067 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1068 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1069 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1070 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1071 log.Fields{"device-id": dh.DeviceID})
1072 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1073 if pDevEntry != nil {
1074 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001075 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001076 } else {
1077 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1078 log.Fields{"device-id": dh.DeviceID})
1079 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1080 if pDevEntry != nil {
1081 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1082 }
1083 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001084 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001085 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001086}
1087
mpagenko101ac942021-11-16 15:01:29 +00001088func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1089 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1090 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1091 flowsProcessed := 0
1092 lastFlowToReconcile := false
1093 loUniID := apUniPort.UniID
1094 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001095 if !(*apFlowsFound) {
1096 *apFlowsFound = true
1097 syncChannel := make(chan struct{})
1098 // start go routine with select() on reconciling vlan config channel before
1099 // starting vlan config reconciling process to prevent loss of any signal
1100 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1101 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1102 //block until the wait routine is really blocked on channel input
1103 // in order to prevent to early ready signal from VlanConfig processing
1104 <-syncChannel
1105 }
1106 if flowsProcessed == len(aPersFlowParam)-1 {
1107 var uniAdded bool
1108 lastFlowToReconcile = true
1109 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1110 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001111 }
1112 }
mpagenko101ac942021-11-16 15:01:29 +00001113 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1114 "device-id": dh.DeviceID, "uni-id": loUniID,
1115 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1116 dh.lockVlanConfig.Lock()
1117 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1118 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1119 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
1120 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1121 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter, nil); err != nil {
1122 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1123 }
1124 } else {
1125 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
1126 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1127 uint8(flowData.VlanRuleParams.SetPcp), cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
1128 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1129 }
1130 }
1131 dh.lockVlanConfig.Unlock()
1132 flowsProcessed++
1133 } //for all flows of this UNI
1134}
1135
1136//waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1137// and decrements the according handler wait group waiting for these indications
1138func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1139 waitGroup *cmn.WaitGroupWithTimeOut) {
1140 var reconciledUniVlanConfigEntries []uint8
1141 var appended bool
1142 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1143 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1144 "device-id": dh.DeviceID, "expiry": expiry})
1145 // indicate blocking on channel now to the caller
1146 aSyncChannel <- struct{}{}
1147 for {
1148 select {
1149 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1150 switch uniIndication {
1151 // no activity requested (should normally not be received) - just continue waiting
1152 case cWaitReconcileFlowNoActivity:
1153 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1154 case cWaitReconcileFlowAbortOnError:
1155 logger.Debugw(ctx, "waitReconcileFlow aborted on error",
1156 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1157 return
1158 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1159 case cWaitReconcileFlowAbortOnSuccess:
1160 logger.Debugw(ctx, "waitReconcileFlow aborted on success",
1161 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1162 return
1163 // this should be a valid UNI vlan config done indication
1164 default:
1165 if uniIndication < platform.MaxUnisPerOnu {
1166 logger.Debugw(ctx, "reconciling flows has been finished in time for this UNI",
1167 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1168 if reconciledUniVlanConfigEntries, appended =
1169 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1170 waitGroup.Done()
1171 }
1172 } else {
1173 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored",
1174 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1175 }
1176 } //switch uniIndication
1177
1178 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1179 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1180 log.Fields{"device-id": dh.DeviceID})
1181 return
1182 }
1183 }
1184}
1185
1186func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1187 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1188}
1189
1190func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1191 for _, ele := range slice {
1192 if ele == val {
1193 return slice, false
1194 }
1195 }
1196 return append(slice, val), true
1197}
1198
1199// sendChReconcileFinished - sends true or false on reconcileFinish channel
1200func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1201 if dh != nil { //if the object still exists (might have been already deleted in background)
1202 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1203 select {
1204 case dh.chReconcilingFinished <- success:
1205 default:
1206 }
1207 }
1208}
1209
1210// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1211func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1212 if dh != nil { //if the object still exists (might have been already deleted in background)
1213 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1214 select {
1215 case dh.chUniVlanConfigReconcilingDone <- value:
1216 default:
1217 }
1218 }
1219}
1220
dbainbri4d3a0dc2020-12-02 00:33:42 +00001221func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001222 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001223
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001224 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001225 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001226 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001227 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001228 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001229 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001230
1231 // deadline context to ensure completion of background routines waited for
1232 //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 +05301233 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001234 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001235
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001236 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001237
1238 var wg sync.WaitGroup
1239 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001240 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001241 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001242
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001243 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001244 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001245}
1246
mpagenko15ff4a52021-03-02 10:09:20 +00001247//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1248// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001249// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001250//was and is called in background - error return does not make sense
1251func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001252 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001253 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001254 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001255 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001256 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001257 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301258 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001259 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001260 return
Himani Chawla4d908332020-08-31 12:30:20 +05301261 }
mpagenko01e726e2020-10-23 09:45:29 +00001262
1263 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001264 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001265
mpagenko44bd8362021-11-15 11:40:05 +00001266 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001267 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001268 // 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 -04001269 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001270 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001271 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001272 OperStatus: voltha.OperStatus_DISCOVERED,
1273 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001274 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001275 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001276 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001277 }
mpagenkoe4782082021-11-25 12:04:26 +00001278 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001279 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001280 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001281 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001282 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1283 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1284 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1285 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001286}
1287
mpagenkoc8bba412021-01-15 15:38:44 +00001288//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001289// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001290func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001291 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001292 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001293 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001294
1295 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001296 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001297 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001298 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1299 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001300 }
1301
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001302 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001303 var inactiveImageID uint16
1304 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1305 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001306 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1307 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001308 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001309 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001310 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001311 if err == nil {
1312 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1313 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001314 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001315 }
1316 } else {
1317 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001318 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001319 }
mpagenko15ff4a52021-03-02 10:09:20 +00001320 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001321 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001322 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001323 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1324 dh.upgradeCanceled = true
1325 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1326 }
mpagenko38662d02021-08-11 09:45:19 +00001327 //no effort spent anymore for the old API to automatically cancel and restart the download
1328 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001329 }
mpagenko15ff4a52021-03-02 10:09:20 +00001330 } else {
1331 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001332 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001333 }
1334 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001335 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1336 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001337 }
1338 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001339}
1340
mpagenkoc26d4c02021-05-06 14:27:57 +00001341//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1342// after the OnuImage has been downloaded to the adapter, called in background
1343func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001344 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001345
1346 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001347 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001348 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001349 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001350 return
1351 }
1352
1353 var inactiveImageID uint16
1354 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1355 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001356 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001357
mpagenko59862f02021-10-11 08:53:18 +00001358 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001359 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001360 // but must be still locked at calling createOnuUpgradeFsm
1361 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1362 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1363 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001364 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1365 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001366 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001367 //flush the remove upgradeFsmChan channel
1368 select {
1369 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001370 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001371 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001372 }
mpagenko59862f02021-10-11 08:53:18 +00001373 dh.lockUpgradeFsm.Unlock()
1374 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1375 dh.upgradeCanceled = true
1376 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1377 }
mpagenko38662d02021-08-11 09:45:19 +00001378 select {
1379 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001380 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001381 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1382 return
1383 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001384 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001385 }
mpagenko59862f02021-10-11 08:53:18 +00001386 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001387 }
mpagenko38662d02021-08-11 09:45:19 +00001388
1389 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001390 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001391 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001392 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001393 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001394 if err == nil {
1395 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1396 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1397 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001398 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001399 return
1400 }
mpagenko38662d02021-08-11 09:45:19 +00001401 } else {
1402 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001403 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001404 }
1405 return
1406 }
1407 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001408 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001409}
1410
1411//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001412func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1413 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001414 var err error
1415 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1416 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1417 // 2.) activation of the inactive image
1418
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001419 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001420 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001421 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1422 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001423 }
1424 dh.lockUpgradeFsm.RLock()
1425 if dh.pOnuUpradeFsm != nil {
1426 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001427 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001428 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001429 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1430 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001431 }
mpagenko59862f02021-10-11 08:53:18 +00001432 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1433 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1434 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1435 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001436 // use the OnuVendor identification from this device for the internal unique name
1437 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001438 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001439 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001440 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001441 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001442 "device-id": dh.DeviceID, "error": err})
1443 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001444 }
mpagenko183647c2021-06-08 15:25:04 +00001445 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001446 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001447 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001448 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001449 } //else
1450 dh.lockUpgradeFsm.RUnlock()
1451
1452 // 2.) check if requested image-version equals the inactive one and start its activation
1453 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1454 var inactiveImageID uint16
1455 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1456 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001457 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1458 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001459 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001460 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001461 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001462 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001463 if err == nil {
1464 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1465 inactiveImageID, aCommitRequest); err != nil {
1466 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001467 "device-id": dh.DeviceID, "error": err})
1468 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001469 }
1470 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001471 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001472 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001473 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001474 } //else
1475 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001476 "device-id": dh.DeviceID, "error": err})
1477 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001478}
1479
1480//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001481func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1482 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001483 var err error
1484 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1485 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1486 // 2.) commitment of the active image
1487
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001488 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001489 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001490 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1491 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001492 }
1493 dh.lockUpgradeFsm.RLock()
1494 if dh.pOnuUpradeFsm != nil {
1495 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001496 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001497 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001498 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1499 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001500 }
mpagenko59862f02021-10-11 08:53:18 +00001501 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1502 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1503 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1504 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001505 // use the OnuVendor identification from this device for the internal unique name
1506 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001507 // 1.) check a started upgrade process and relay the commitment request to it
1508 // the running upgrade may be based either on the imageIdentifier (started from download)
1509 // or on the imageVersion (started from pure activation)
1510 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1511 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001512 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001513 "device-id": dh.DeviceID, "error": err})
1514 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001515 }
mpagenko183647c2021-06-08 15:25:04 +00001516 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001517 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001518 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001519 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001520 } //else
1521 dh.lockUpgradeFsm.RUnlock()
1522
mpagenko183647c2021-06-08 15:25:04 +00001523 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001524 var activeImageID uint16
1525 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1526 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001527 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1528 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001529 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001530 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001531 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001532 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001533 if err == nil {
1534 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1535 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001536 "device-id": dh.DeviceID, "error": err})
1537 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001538 }
1539 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001540 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001541 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001542 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001543 } //else
1544 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001545 "device-id": dh.DeviceID, "error": err})
1546 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001547}
1548
mpagenkoaa3afe92021-05-21 16:20:58 +00001549func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001550 aVersion string) *voltha.ImageState {
1551 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001552 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001553 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001554 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001555 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1556 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1557 if aVersion == dh.pLastUpgradeImageState.Version {
1558 pImageState = dh.pLastUpgradeImageState
1559 } else { //state request for an image version different from last processed image version
1560 pImageState = &voltha.ImageState{
1561 Version: aVersion,
1562 //we cannot state something concerning this version
1563 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1564 Reason: voltha.ImageState_NO_ERROR,
1565 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1566 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001567 }
1568 }
mpagenko38662d02021-08-11 09:45:19 +00001569 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001570}
1571
1572func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1573 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001574 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001575 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001576 dh.lockUpgradeFsm.RLock()
1577 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001578 dh.lockUpgradeFsm.RUnlock()
1579 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001580 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001581 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1582 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1583 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1584 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1585 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1586 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001587 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1588 dh.upgradeCanceled = true
1589 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1590 }
mpagenko45586762021-10-01 08:30:22 +00001591 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001592 } else {
mpagenko45586762021-10-01 08:30:22 +00001593 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001594 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1595 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1596 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1597 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1598 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1599 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001600 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1601 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001602 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1603 //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 +00001604 }
1605}
1606
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001607func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1608
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001609 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001610
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001611 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001612 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001613 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1614 pDevEntry.MutexOnuImageStatus.Lock()
1615 pDevEntry.POnuImageStatus = onuImageStatus
1616 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001617
1618 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001619 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001620 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1621 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001622 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1623 pDevEntry.MutexOnuImageStatus.Lock()
1624 pDevEntry.POnuImageStatus = nil
1625 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001626 return images, err
1627}
1628
Himani Chawla6d2ae152020-09-02 13:11:20 +05301629// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001630// #####################################################################################
1631
1632// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301633// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001634
dbainbri4d3a0dc2020-12-02 00:33:42 +00001635func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001636 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1637 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001638}
1639
1640// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001641func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001642
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001643 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001644 var err error
1645
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001646 // populate what we know. rest comes later after mib sync
1647 dh.device.Root = false
1648 dh.device.Vendor = "OpenONU"
1649 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001650 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001651 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001652
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001653 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001654
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001655 if !dh.IsReconciling() {
1656 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001657 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1658 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1659 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301660 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001661 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001662 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001663 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001664 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001665
Himani Chawla4d908332020-08-31 12:30:20 +05301666 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001667 dh.ponPortNumber = dh.device.ParentPortNo
1668
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001669 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1670 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1671 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001672 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001673 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301674 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001675
1676 /*
1677 self._pon = PonPort.create(self, self._pon_port_number)
1678 self._pon.add_peer(self.parent_id, self._pon_port_number)
1679 self.logger.debug('adding-pon-port-to-agent',
1680 type=self._pon.get_port().type,
1681 admin_state=self._pon.get_port().admin_state,
1682 oper_status=self._pon.get_port().oper_status,
1683 )
1684 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001685 if !dh.IsReconciling() {
1686 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001687 var ponPortNo uint32 = 1
1688 if dh.ponPortNumber != 0 {
1689 ponPortNo = dh.ponPortNumber
1690 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001691
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001692 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001693 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001694 PortNo: ponPortNo,
1695 Label: fmt.Sprintf("pon-%d", ponPortNo),
1696 Type: voltha.Port_PON_ONU,
1697 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301698 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001699 PortNo: ponPortNo}}, // Peer port is parent's port number
1700 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001701 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001702 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001703 e.Cancel(err)
1704 return
1705 }
1706 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001707 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001708 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001709 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001710}
1711
1712// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001713func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001714
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001715 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001716 var err error
1717 /*
1718 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1719 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1720 return nil
1721 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001722 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001723 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001724 e.Cancel(err)
1725 return
1726 }
1727
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001728 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001729 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001730 // reconcilement will be continued after mib download is done
1731 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001732
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001733 /*
1734 ############################################################################
1735 # Setup Alarm handler
1736 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1737 device.serial_number)
1738 ############################################################################
1739 # Setup PM configuration for this device
1740 # Pass in ONU specific options
1741 kwargs = {
1742 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1743 'heartbeat': self.heartbeat,
1744 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1745 }
1746 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1747 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1748 self.logical_device_id, device.serial_number,
1749 grouped=True, freq_override=False, **kwargs)
1750 pm_config = self._pm_metrics.make_proto()
1751 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1752 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1753 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1754
1755 # Note, ONU ID and UNI intf set in add_uni_port method
1756 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1757 ani_ports=[self._pon])
1758
1759 # Code to Run OMCI Test Action
1760 kwargs_omci_test_action = {
1761 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1762 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1763 }
1764 serial_number = device.serial_number
1765 self._test_request = OmciTestRequest(self.core_proxy,
1766 self.omci_agent, self.device_id,
1767 AniG, serial_number,
1768 self.logical_device_id,
1769 exclusive=False,
1770 **kwargs_omci_test_action)
1771
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001772 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001773 else:
1774 self.logger.info('onu-already-activated')
1775 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001776
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001777 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001778}
1779
1780// doStateConnected get the device info and update to voltha core
1781// for comparison of the original method (not that easy to uncomment): compare here:
1782// voltha-openolt-adapter/adaptercore/device_handler.go
1783// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001784func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001785
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001786 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301787 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001788 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001789 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001790}
1791
1792// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001793func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001794
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001795 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301796 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001797 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001798 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001799
1800 /*
1801 // Synchronous call to update device state - this method is run in its own go routine
1802 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1803 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001804 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 +00001805 return err
1806 }
1807 return nil
1808 */
1809}
1810
1811// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001812func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001813
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001814 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001815 var err error
1816
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001817 device := dh.device
1818 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001819 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001820 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001821 e.Cancel(err)
1822 return
1823 }
1824
1825 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001826 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001827 /*
1828 // Update the all ports state on that device to disable
1829 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001830 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001831 return er
1832 }
1833
1834 //Update the device oper state and connection status
1835 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1836 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1837 dh.device = cloned
1838
1839 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001840 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001841 return er
1842 }
1843
1844 //get the child device for the parent device
1845 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1846 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001847 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001848 return err
1849 }
1850 for _, onuDevice := range onuDevices.Items {
1851
1852 // Update onu state as down in onu adapter
1853 onuInd := oop.OnuIndication{}
1854 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001855 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001856 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1857 if er != nil {
1858 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001859 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001860 //Do not return here and continue to process other ONUs
1861 }
1862 }
1863 // * Discovered ONUs entries need to be cleared , since after OLT
1864 // is up, it starts sending discovery indications again* /
1865 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001866 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001867 return nil
1868 */
Himani Chawla4d908332020-08-31 12:30:20 +05301869 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001870 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001871 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001872}
1873
Himani Chawla6d2ae152020-09-02 13:11:20 +05301874// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001875// #################################################################################
1876
1877// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301878// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001879
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001880//GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
1881func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001882 dh.lockDevice.RLock()
1883 pOnuDeviceEntry := dh.pOnuOmciDevice
1884 if aWait && pOnuDeviceEntry == nil {
1885 //keep the read sema short to allow for subsequent write
1886 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001887 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001888 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1889 // so it might be needed to wait here for that event with some timeout
1890 select {
1891 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001892 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001893 return nil
1894 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001895 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001896 // if written now, we can return the written value without sema
1897 return dh.pOnuOmciDevice
1898 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001899 }
mpagenko3af1f032020-06-10 08:53:41 +00001900 dh.lockDevice.RUnlock()
1901 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001902}
1903
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001904//setDeviceHandlerEntries sets the ONU device entry within the handler
1905func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1906 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001907 dh.lockDevice.Lock()
1908 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001909 dh.pOnuOmciDevice = apDeviceEntry
1910 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001911 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301912 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001913 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001914}
1915
Himani Chawla6d2ae152020-09-02 13:11:20 +05301916//addOnuDeviceEntry creates a new ONU device or returns the existing
1917func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001918 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001919
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001920 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001921 if deviceEntry == nil {
1922 /* costum_me_map in python code seems always to be None,
1923 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1924 /* also no 'clock' argument - usage open ...*/
1925 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001926 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1927 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1928 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1929 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1930 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001931 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001932 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001933 // fire deviceEntry ready event to spread to possibly waiting processing
1934 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001935 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001936 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001937 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001938 }
1939 // might be updated with some error handling !!!
1940 return nil
1941}
1942
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001944 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001945 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1946
1947 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001948
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001949 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001950 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001951 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1952 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001953 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001954 if !dh.IsReconciling() {
1955 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001956 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001957 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001958 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001960 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001961
khenaidoo42dcdfd2021-10-19 17:34:12 -04001962 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001963 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001964 OperStatus: voltha.OperStatus_ACTIVATING,
1965 ConnStatus: voltha.ConnectStatus_REACHABLE,
1966 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001967 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001968 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001969 }
1970 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001971 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001972 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001973
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001974 pDevEntry.MutexPersOnuConfig.RLock()
1975 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1976 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001977 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 +00001978 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001979 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001980 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001981 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001982 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001983 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001984 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1985 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1986 // 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 +00001987 // 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 +00001988 // so let's just try to keep it simple ...
1989 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001990 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001991 if err != nil || device == nil {
1992 //TODO: needs to handle error scenarios
1993 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1994 return errors.New("Voltha Device not found")
1995 }
1996 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001997
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001998 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001999 return err
mpagenko3af1f032020-06-10 08:53:41 +00002000 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002001 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002002
2003 /* this might be a good time for Omci Verify message? */
2004 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002005 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00002006 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00002007 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002008 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002009
2010 /* give the handler some time here to wait for the OMCi verification result
2011 after Timeout start and try MibUpload FSM anyway
2012 (to prevent stopping on just not supported OMCI verification from ONU) */
2013 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002014 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002015 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002016 case testresult := <-verifyExec:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002017 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002018 }
2019
2020 /* In py code it looks earlier (on activate ..)
2021 # Code to Run OMCI Test Action
2022 kwargs_omci_test_action = {
2023 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2024 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2025 }
2026 serial_number = device.serial_number
2027 self._test_request = OmciTestRequest(self.core_proxy,
2028 self.omci_agent, self.device_id,
2029 AniG, serial_number,
2030 self.logical_device_id,
2031 exclusive=False,
2032 **kwargs_omci_test_action)
2033 ...
2034 # Start test requests after a brief pause
2035 if not self._test_request_started:
2036 self._test_request_started = True
2037 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2038 reactor.callLater(tststart, self._test_request.start_collector)
2039
2040 */
2041 /* which is then: in omci_test_request.py : */
2042 /*
2043 def start_collector(self, callback=None):
2044 """
2045 Start the collection loop for an adapter if the frequency > 0
2046
2047 :param callback: (callable) Function to call to collect PM data
2048 """
2049 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2050 if callback is None:
2051 callback = self.perform_test_omci
2052
2053 if self.lc is None:
2054 self.lc = LoopingCall(callback)
2055
2056 if self.default_freq > 0:
2057 self.lc.start(interval=self.default_freq / 10)
2058
2059 def perform_test_omci(self):
2060 """
2061 Perform the initial test request
2062 """
2063 ani_g_entities = self._device.configuration.ani_g_entities
2064 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2065 is not None else None
2066 self._entity_id = ani_g_entities_ids[0]
2067 self.logger.info('perform-test', entity_class=self._entity_class,
2068 entity_id=self._entity_id)
2069 try:
2070 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2071 result = yield self._device.omci_cc.send(frame)
2072 if not result.fields['omci_message'].fields['success_code']:
2073 self.logger.info('Self-Test Submitted Successfully',
2074 code=result.fields[
2075 'omci_message'].fields['success_code'])
2076 else:
2077 raise TestFailure('Test Failure: {}'.format(
2078 result.fields['omci_message'].fields['success_code']))
2079 except TimeoutError as e:
2080 self.deferred.errback(failure.Failure(e))
2081
2082 except Exception as e:
2083 self.logger.exception('perform-test-Error', e=e,
2084 class_id=self._entity_class,
2085 entity_id=self._entity_id)
2086 self.deferred.errback(failure.Failure(e))
2087
2088 */
2089
2090 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002091 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002092
mpagenko1cc3cb42020-07-27 15:24:38 +00002093 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2094 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2095 * 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 +05302096 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002097 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002098 //call MibUploadFSM - transition up to state UlStInSync
2099 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002100 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002101 if pMibUlFsm.Is(mib.UlStDisabled) {
2102 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2103 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2104 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302105 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002106 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302107 //Determine ONU status and start/re-start MIB Synchronization tasks
2108 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002109 if pDevEntry.IsNewOnu() {
2110 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2111 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2112 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002113 }
Himani Chawla4d908332020-08-31 12:30:20 +05302114 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002115 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2116 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2117 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302118 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002119 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002120 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002121 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002122 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002123 "device-id": dh.DeviceID})
2124 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002125 }
2126 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002127 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2128 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002129 }
2130 return nil
2131}
2132
dbainbri4d3a0dc2020-12-02 00:33:42 +00002133func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00002134 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002135 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002136 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
2137 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002138
mpagenko900ee4b2020-10-12 11:56:34 +00002139 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2140 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2141 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002142 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002143 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002144 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002145 // abort: system behavior is just unstable ...
2146 return err
2147 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002148 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002149 _ = 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 +00002150
2151 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002152 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002153 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002154 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002155 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2156 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002157 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002158 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002159
2160 //TODO!!! remove existing traffic profiles
2161 /* from py code, if TP's exist, remove them - not yet implemented
2162 self._tp = dict()
2163 # Let TP download happen again
2164 for uni_id in self._tp_service_specific_task:
2165 self._tp_service_specific_task[uni_id].clear()
2166 for uni_id in self._tech_profile_download_done:
2167 self._tech_profile_download_done[uni_id].clear()
2168 */
2169
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002170 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002171
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002172 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002173
mpagenkoe4782082021-11-25 12:04:26 +00002174 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002175 // abort: system behavior is just unstable ...
2176 return err
2177 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002178 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002179 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002180 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002181 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002182 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2183 OperStatus: voltha.OperStatus_DISCOVERED,
2184 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002185 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002186 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002187 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002188 // abort: system behavior is just unstable ...
2189 return err
2190 }
2191 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002192 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002193 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002194 return nil
2195}
2196
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002197func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002198 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2199 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2200 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2201 // and using the stop/reset event should never harm
2202
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002203 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002204 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002205 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2206 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00002207 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002208 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002209 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002210 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002211 pDevEntry.MutexOnuImageStatus.RLock()
2212 if pDevEntry.POnuImageStatus != nil {
2213 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002214 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002215 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002216
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002217 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002218 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002219 }
2220 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002221 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002222 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002223 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002224 }
mpagenko101ac942021-11-16 15:01:29 +00002225 //stop any deviceHandler reconcile processing (if running)
2226 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002227 //port lock/unlock FSM's may be active
2228 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002229 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002230 }
2231 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002232 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002233 }
2234 //techProfile related PonAniConfigFsm FSM may be active
2235 if dh.pOnuTP != nil {
2236 // should always be the case here
2237 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002238 if dh.pOnuTP.PAniConfigFsm != nil {
2239 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2240 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002241 }
mpagenko900ee4b2020-10-12 11:56:34 +00002242 }
2243 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002244 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002245 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002246 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002247 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002248 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002249 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002250 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002251 } else {
2252 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002253 }
2254 }
2255 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002256 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002257 // Stop collector routine
2258 dh.stopCollector <- true
2259 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002260 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302261 dh.stopAlarmManager <- true
2262 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002263 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002264 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002265 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302266
Girish Gowdrae95687a2021-09-08 16:30:58 -07002267 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2268
mpagenko80622a52021-02-09 16:53:23 +00002269 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002270 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002271 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002272 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002273 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002274 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002275 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002276 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2277 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2278 // (even though it may also run into direct cancellation, a bit hard to verify here)
2279 // so don't set 'dh.upgradeCanceled = true' here!
2280 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2281 }
mpagenko38662d02021-08-11 09:45:19 +00002282 }
mpagenko80622a52021-02-09 16:53:23 +00002283
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002284 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002285 return nil
2286}
2287
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002288func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2289 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 +05302290
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002291 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002292 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002293 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002294 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002295 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002296 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002297 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002298
mpagenkoa40e99a2020-11-17 13:50:39 +00002299 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2300 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2301 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2302 * disable/enable toggling here to allow traffic
2303 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2304 * like the py comment says:
2305 * # start by locking all the unis till mib sync and initial mib is downloaded
2306 * # this way we can capture the port down/up events when we are ready
2307 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302308
mpagenkoa40e99a2020-11-17 13:50:39 +00002309 // Init Uni Ports to Admin locked state
2310 // *** should generate UniLockStateDone event *****
2311 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002312 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002313 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002314 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002315 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002316 }
2317}
2318
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002319func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2320 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302321 /* Mib download procedure -
2322 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2323 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002324 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002325 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002326 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002327 return
2328 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002329 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302330 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002331 if pMibDlFsm.Is(mib.DlStDisabled) {
2332 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2333 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 +05302334 // maybe try a FSM reset and then again ... - TODO!!!
2335 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002336 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302337 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002338 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2339 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302340 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002341 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302342 //Begin MIB data download (running autonomously)
2343 }
2344 }
2345 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002346 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002347 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302348 // maybe try a FSM reset and then again ... - TODO!!!
2349 }
2350 /***** Mib download started */
2351 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002352 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302353 }
2354}
2355
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002356func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2357 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302358 //initiate DevStateUpdate
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002359 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002360 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002361 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002362 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2363 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2364 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2365 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002366 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002367 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002368 ConnStatus: voltha.ConnectStatus_REACHABLE,
2369 OperStatus: voltha.OperStatus_ACTIVE,
2370 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302371 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002372 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302373 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002374 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302375 }
2376 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002377 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002378 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302379 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002380 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002381
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002382 if !dh.GetCollectorIsRunning() {
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002383 // Start PM collector routine
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002384 go dh.StartCollector(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002385 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002386 if !dh.GetAlarmManagerIsRunning(ctx) {
2387 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002388 }
2389
Girish Gowdrae95687a2021-09-08 16:30:58 -07002390 // Start flow handler routines per UNI
2391 for _, uniPort := range dh.uniEntityMap {
2392 // only if this port was enabled for use by the operator at startup
2393 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2394 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2395 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2396 }
2397 }
2398 }
2399
Girish Gowdrae0140f02021-02-02 16:55:09 -08002400 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002401 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002402 // There is no way we should be landing here, but if we do then
2403 // there is nothing much we can do about this other than log error
2404 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2405 }
2406
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002407 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002408
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002409 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002410 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002411 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002412 return
2413 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002414 pDevEntry.MutexPersOnuConfig.RLock()
2415 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2416 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002417 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002418 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002419 dh.mutexForDisableDeviceRequested.Lock()
2420 dh.disableDeviceRequested = true
2421 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002422 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002423 // reconcilement will be continued after ani config is done
2424 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002425 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002426 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002427 dh.mutexForDisableDeviceRequested.RLock()
2428 if !dh.disableDeviceRequested {
2429 if dh.pUnlockStateFsm == nil {
2430 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2431 } else { //UnlockStateFSM already init
2432 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2433 dh.runUniLockFsm(ctx, false)
2434 }
2435 dh.mutexForDisableDeviceRequested.RUnlock()
2436 } else {
2437 dh.mutexForDisableDeviceRequested.RUnlock()
2438 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002439 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302440 }
2441}
2442
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002443func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2444 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302445
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002446 if !dh.IsReconciling() {
2447 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002448 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002449 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2450 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002451 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002452 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002453 return
2454 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002455 pDevEntry.MutexPersOnuConfig.Lock()
2456 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2457 pDevEntry.MutexPersOnuConfig.Unlock()
2458 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002459 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002460 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002461 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302462 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002463 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 +00002464 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002465 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002466 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302467 }
2468}
2469
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002470func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002471 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002472 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002473
mpagenko44bd8362021-11-15 11:40:05 +00002474 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002475 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002476 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002477 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002478 OperStatus: voltha.OperStatus_UNKNOWN,
2479 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002480 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002481 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002482 }
2483
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002484 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002485 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002486 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002487
2488 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002489 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002490
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002491 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002492 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002493 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002494 return
2495 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002496 pDevEntry.MutexPersOnuConfig.Lock()
2497 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2498 pDevEntry.MutexPersOnuConfig.Unlock()
2499 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002500 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002501 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002502 }
mpagenko900ee4b2020-10-12 11:56:34 +00002503}
2504
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002505func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002506 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002507 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002508 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002509 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002510 ConnStatus: voltha.ConnectStatus_REACHABLE,
2511 OperStatus: voltha.OperStatus_ACTIVE,
2512 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002513 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002514 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002515 }
2516
dbainbri4d3a0dc2020-12-02 00:33:42 +00002517 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002518 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002519 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002520 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002521
2522 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002523 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002524
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002525 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002526 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002527 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002528 return
2529 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002530 pDevEntry.MutexPersOnuConfig.Lock()
2531 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2532 pDevEntry.MutexPersOnuConfig.Unlock()
2533 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002534 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002535 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002536 }
mpagenko900ee4b2020-10-12 11:56:34 +00002537}
2538
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002539func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2540 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2541 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002542 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002543 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002544 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002545 OperStatus: voltha.OperStatus_FAILED,
2546 }); err != nil {
2547 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2548 }
2549}
2550
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002551func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2552 if devEvent == cmn.OmciAniConfigDone {
2553 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002554 // attention: the device reason update is done based on ONU-UNI-Port related activity
2555 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002556 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002557 // 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 +00002558 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302559 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002560 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002561 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
2562 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
2563 dh.mutexReconcilingFirstPassFlag.Lock()
2564 if dh.reconcilingFirstPass {
2565 logger.Debugw(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
2566 dh.reconcilingFirstPass = false
2567 go dh.ReconcileDeviceFlowConfig(ctx)
2568 }
2569 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00002570 }
2571 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002572 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002573 // attention: the device reason update is done based on ONU-UNI-Port related activity
2574 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002575 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002576 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
2577 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002578 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002579 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302580}
2581
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002582func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002583 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002584 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302585 // attention: the device reason update is done based on ONU-UNI-Port related activity
2586 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302587
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002588 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2589 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00002590 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00002591 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002592 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00002593 }
2594 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002595 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002596 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00002597 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002598 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302599 }
mpagenkof1fc3862021-02-16 10:09:52 +00002600
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002601 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002602 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002603 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002604 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002605 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002606 }
2607 } else {
2608 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002609 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002610 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302611}
2612
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002613//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
2614func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302615 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002616 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002617 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002618 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002619 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002620 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002621 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002622 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002623 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002624 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002625 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002626 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002627 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002628 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002629 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002630 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002631 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002632 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002633 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002634 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002635 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002636 case cmn.UniEnableStateFailed:
2637 {
2638 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2639 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002640 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002641 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002642 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002643 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002644 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002645 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002646 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002647 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002648 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002649 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002650 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002651 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002652 default:
2653 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002654 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002655 }
2656 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002657}
2658
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002659func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002660 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002661 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302662 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002663 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002664 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002665 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302666 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002667 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002668 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002669 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 +00002670 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002671 //store UniPort with the System-PortNumber key
2672 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002673 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002674 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002675 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002676 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002677 } //error logging already within UniPort method
2678 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002679 logger.Debugw(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002680 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002681 }
2682 }
2683}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002684
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002685func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2686 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002687 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002688 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002689 return
2690 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002691 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002692 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002693 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2694 for _, mgmtEntityID := range pptpInstKeys {
2695 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002696 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002697 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2698 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002699 }
2700 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002701 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002702 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002703 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002704 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2705 for _, mgmtEntityID := range veipInstKeys {
2706 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002707 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002708 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2709 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002710 }
2711 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002712 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002713 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002714 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002715 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2716 for _, mgmtEntityID := range potsInstKeys {
2717 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002718 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002719 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2720 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002721 }
2722 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002723 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002724 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002725 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002726 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002727 return
2728 }
2729
mpagenko2c3f6c52021-11-23 11:22:10 +00002730 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
2731 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
2732 // 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 -07002733 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2734 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2735 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00002736 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
2737 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002738 for i := 0; i < int(uniCnt); i++ {
2739 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
2740 dh.stopFlowMonitoringRoutine[i] = make(chan bool)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002741 }
2742}
2743
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002744// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2745func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002746 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302747 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002748 // with following remark:
2749 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2750 // # load on the core
2751
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002752 // 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 +00002753
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002754 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002755 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002756 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2757 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2758 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2759 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002760 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002761 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002762 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002763 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002764 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002765 PortNo: port.PortNo,
2766 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002767 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002768 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 -04002769 }
2770 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002771 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002772 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002773 }
mpagenko3af1f032020-06-10 08:53:41 +00002774 }
2775 }
2776}
2777
2778// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002779func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2780 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002781 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2782 for uniNo, uniPort := range dh.uniEntityMap {
2783 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002784
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002785 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2786 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2787 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2788 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002789 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002790 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002791 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002792 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002793 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002794 PortNo: port.PortNo,
2795 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002796 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002797 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 -04002798 }
2799 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002800 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002801 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002802 }
2803
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002804 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002805 }
2806}
2807
2808// ONU_Active/Inactive announcement on system KAFKA bus
2809// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002810func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002811 var de voltha.DeviceEvent
2812 eventContext := make(map[string]string)
2813 //Populating event context
2814 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002815 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002816 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002817 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002818 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002819 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 +00002820 }
2821 oltSerialNumber := parentDevice.SerialNumber
2822
2823 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2824 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2825 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302826 eventContext["olt-serial-number"] = oltSerialNumber
2827 eventContext["device-id"] = aDeviceID
2828 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002829 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002830 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2831 deviceEntry.MutexPersOnuConfig.RLock()
2832 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2833 deviceEntry.MutexPersOnuConfig.RUnlock()
2834 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
2835 deviceEntry.MutexPersOnuConfig.RLock()
2836 eventContext["vendor"] = deviceEntry.SOnuPersistentData.PersVendorID
2837 deviceEntry.MutexPersOnuConfig.RUnlock()
2838 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002839 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2840 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2841 } else {
2842 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2843 log.Fields{"device-id": aDeviceID})
2844 return
2845 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002846
2847 /* Populating device event body */
2848 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302849 de.ResourceId = aDeviceID
2850 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002851 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2852 de.Description = fmt.Sprintf("%s Event - %s - %s",
2853 cEventObjectType, cOnuActivatedEvent, "Raised")
2854 } else {
2855 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2856 de.Description = fmt.Sprintf("%s Event - %s - %s",
2857 cEventObjectType, cOnuActivatedEvent, "Cleared")
2858 }
2859 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002860 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2861 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302862 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002863 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002864 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302865 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002866}
2867
Himani Chawla4d908332020-08-31 12:30:20 +05302868// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002869func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2870 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002871 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302872 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002873 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002874 sFsmName = "LockStateFSM"
2875 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002876 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002877 sFsmName = "UnLockStateFSM"
2878 }
mpagenko3af1f032020-06-10 08:53:41 +00002879
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002880 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002881 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002882 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002883 return
2884 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002885 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002886 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302887 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002888 dh.pLockStateFsm = pLSFsm
2889 } else {
2890 dh.pUnlockStateFsm = pLSFsm
2891 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002892 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002893 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002894 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002895 }
2896}
2897
2898// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002899func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002900 /* Uni Port lock/unlock procedure -
2901 ***** should run via 'adminDone' state and generate the argument requested event *****
2902 */
2903 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302904 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002905 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002906 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2907 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002908 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2909 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002910 }
2911 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002912 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002913 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2914 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002915 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2916 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002917 }
2918 }
2919 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002920 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2921 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002922 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002923 // maybe try a FSM reset and then again ... - TODO!!!
2924 } else {
2925 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002926 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002927 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002928 }
2929 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002930 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002931 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002932 // maybe try a FSM reset and then again ... - TODO!!!
2933 }
2934 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002935 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002936 // maybe try a FSM reset and then again ... - TODO!!!
2937 }
2938}
2939
mpagenko80622a52021-02-09 16:53:23 +00002940// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00002941// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002942func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002943 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002944 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002945 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002946 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002947 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002948 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002949 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002950 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002951 sFsmName, chUpgradeFsm)
2952 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002953 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00002954 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002955 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
2956 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002957 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00002958 // maybe try a FSM reset and then again ... - TODO!!!
2959 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2960 }
mpagenko59862f02021-10-11 08:53:18 +00002961 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00002962 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2963 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00002964 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2965 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002966 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002967 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002968 } else {
2969 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002970 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002971 // maybe try a FSM reset and then again ... - TODO!!!
2972 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2973 }
2974 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002975 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002976 // maybe try a FSM reset and then again ... - TODO!!!
2977 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2978 }
2979 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002980 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002981 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2982 }
2983 return nil
2984}
2985
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002986// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
2987func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002988 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002989 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002990 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00002991 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2992 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00002993 dh.pLastUpgradeImageState = apImageState
2994 dh.lockUpgradeFsm.Unlock()
2995 //signal upgradeFsm removed using non-blocking channel send
2996 select {
2997 case dh.upgradeFsmChan <- struct{}{}:
2998 default:
2999 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003000 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003001 }
mpagenko80622a52021-02-09 16:53:23 +00003002}
3003
mpagenko15ff4a52021-03-02 10:09:20 +00003004// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3005func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003006 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003007 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003008 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003009 return
3010 }
3011
3012 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003013 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003014 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003015 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3016 dh.lockUpgradeFsm.RUnlock()
3017 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3018 return
3019 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003020 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003021 if pUpgradeStatemachine != nil {
3022 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3023 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003024 UpgradeState := pUpgradeStatemachine.Current()
3025 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3026 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3027 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003028 // 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 +00003029 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003030 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3031 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003032 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003033 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003034 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003035 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3036 dh.upgradeCanceled = true
3037 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3038 }
mpagenko15ff4a52021-03-02 10:09:20 +00003039 return
3040 }
mpagenko59862f02021-10-11 08:53:18 +00003041 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003042 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3043 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003044 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003045 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003046 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3047 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003048 return
3049 }
3050 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003051 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003052 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003053 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3054 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003055 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3056 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003057 return
3058 }
3059 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003060 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003061 }
3062 } else {
3063 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 +00003064 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003065 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3066 dh.upgradeCanceled = true
3067 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3068 }
mpagenko1f8e8822021-06-25 14:10:21 +00003069 }
mpagenko15ff4a52021-03-02 10:09:20 +00003070 return
3071 }
mpagenko59862f02021-10-11 08:53:18 +00003072 dh.lockUpgradeFsm.RUnlock()
3073 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3074 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003075 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3076 dh.upgradeCanceled = true
3077 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3078 }
mpagenko59862f02021-10-11 08:53:18 +00003079 return
3080 }
3081 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3082 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3083 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3084 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3085 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3086 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3087 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003088 }
mpagenko15ff4a52021-03-02 10:09:20 +00003089 }
3090 }
3091 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003092 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003093 }
mpagenko59862f02021-10-11 08:53:18 +00003094 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003095}
3096
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003097//SetBackend provides a DB backend for the specified path on the existing KV client
3098func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003099
3100 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003101 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003102 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003103 kvbackend := &db.Backend{
3104 Client: dh.pOpenOnuAc.kvClient,
3105 StoreType: dh.pOpenOnuAc.KVStoreType,
3106 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003107 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003108 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3109 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003110
mpagenkoaf801632020-07-03 10:00:42 +00003111 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003112}
khenaidoo7d3c5582021-08-11 18:09:44 -04003113func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05303114 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003115
mpagenkodff5dda2020-08-28 11:52:01 +00003116 for _, field := range flow.GetOfbFields(apFlowItem) {
3117 switch field.Type {
3118 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3119 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003120 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003121 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3122 }
mpagenko01e726e2020-10-23 09:45:29 +00003123 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003124 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3125 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303126 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003127 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303128 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3129 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003130 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3131 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003132 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003133 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303134 return
mpagenkodff5dda2020-08-28 11:52:01 +00003135 }
3136 }
mpagenko01e726e2020-10-23 09:45:29 +00003137 */
mpagenkodff5dda2020-08-28 11:52:01 +00003138 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3139 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303140 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003141 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303142 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003143 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303144 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003145 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003146 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303147 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003148 }
3149 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3150 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303151 *loAddPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003152 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003153 "PCP": loAddPcp})
3154 }
3155 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3156 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003157 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003158 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3159 }
3160 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3161 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003162 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003163 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3164 }
3165 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3166 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003167 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003168 "IPv4-DST": field.GetIpv4Dst()})
3169 }
3170 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3171 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003172 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003173 "IPv4-SRC": field.GetIpv4Src()})
3174 }
3175 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3176 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003177 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003178 "Metadata": field.GetTableMetadata()})
3179 }
3180 /*
3181 default:
3182 {
3183 //all other entires ignored
3184 }
3185 */
3186 }
3187 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303188}
mpagenkodff5dda2020-08-28 11:52:01 +00003189
khenaidoo7d3c5582021-08-11 18:09:44 -04003190func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003191 for _, action := range flow.GetActions(apFlowItem) {
3192 switch action.Type {
3193 /* not used:
3194 case of.OfpActionType_OFPAT_OUTPUT:
3195 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003196 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003197 "Output": action.GetOutput()})
3198 }
3199 */
3200 case of.OfpActionType_OFPAT_PUSH_VLAN:
3201 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003202 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003203 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3204 }
3205 case of.OfpActionType_OFPAT_SET_FIELD:
3206 {
3207 pActionSetField := action.GetSetField()
3208 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003209 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003210 "OxcmClass": pActionSetField.Field.OxmClass})
3211 }
3212 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303213 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003214 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303215 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003216 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303217 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003218 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303219 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003220 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003221 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003222 "Type": pActionSetField.Field.GetOfbField().Type})
3223 }
3224 }
3225 /*
3226 default:
3227 {
3228 //all other entires ignored
3229 }
3230 */
3231 }
3232 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303233}
3234
3235//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003236func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003237 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303238 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3239 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
3240 var loAddPcp, loSetPcp uint8
3241 var loIPProto uint32
3242 /* the TechProfileId is part of the flow Metadata - compare also comment within
3243 * OLT-Adapter:openolt_flowmgr.go
3244 * Metadata 8 bytes:
3245 * Most Significant 2 Bytes = Inner VLAN
3246 * Next 2 Bytes = Tech Profile ID(TPID)
3247 * Least Significant 4 Bytes = Port ID
3248 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3249 * subscriber related flows.
3250 */
3251
dbainbri4d3a0dc2020-12-02 00:33:42 +00003252 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303253 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003254 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003255 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003256 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303257 }
mpagenko551a4d42020-12-08 18:09:20 +00003258 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003259 loCookie := apFlowItem.GetCookie()
3260 loCookieSlice := []uint64{loCookie}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003261 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003262 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05303263
dbainbri4d3a0dc2020-12-02 00:33:42 +00003264 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003265 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303266 if loIPProto == 2 {
3267 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3268 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003269 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003270 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303271 return nil
3272 }
mpagenko01e726e2020-10-23 09:45:29 +00003273 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003274 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003275
3276 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003277 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003278 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003279 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3280 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3281 //TODO!!: Use DeviceId within the error response to rwCore
3282 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003283 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003284 }
3285 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003286 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003287 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3288 } else {
3289 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3290 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3291 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303292 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003293 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003294 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003295 }
mpagenko9a304ea2020-12-16 15:54:01 +00003296
khenaidoo42dcdfd2021-10-19 17:34:12 -04003297 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003298 if apFlowMetaData != nil {
3299 meter = apFlowMetaData.Meters[0]
3300 }
mpagenkobc4170a2021-08-17 16:42:10 +00003301 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3302 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3303 // when different rules are requested concurrently for the same uni
3304 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3305 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3306 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003307 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3308 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003309 //SetUniFlowParams() may block on some rule that is suspended-to-add
3310 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003311 // Also the error is returned to caller via response channel
3312 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
3313 loMatchVlan, loSetVlan, loSetPcp, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003314 dh.lockVlanConfig.RUnlock()
3315 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003316 return
mpagenkodff5dda2020-08-28 11:52:01 +00003317 }
mpagenkobc4170a2021-08-17 16:42:10 +00003318 dh.lockVlanConfig.RUnlock()
3319 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003320 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003321 loMatchVlan, loSetVlan, loSetPcp, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003322 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003323 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003324 if err != nil {
3325 *respChan <- err
3326 }
mpagenko01e726e2020-10-23 09:45:29 +00003327}
3328
3329//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003330func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003331 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3332 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3333 //no extra check is done on the rule parameters
3334 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3335 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3336 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3337 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003338 // - 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 +00003339 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003340 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003341
3342 /* TT related temporary workaround - should not be needed anymore
3343 for _, field := range flow.GetOfbFields(apFlowItem) {
3344 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3345 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003346 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003347 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3348 if loIPProto == 2 {
3349 // 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 +00003350 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003351 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003352 return nil
3353 }
3354 }
3355 } //for all OfbFields
3356 */
3357
mpagenko9a304ea2020-12-16 15:54:01 +00003358 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003359 dh.lockVlanConfig.RLock()
3360 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003361 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3362 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003363 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3364 return
mpagenko01e726e2020-10-23 09:45:29 +00003365 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003366 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003367 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003368 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003369 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003370 // Push response on the response channel
3371 if respChan != nil {
3372 // 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
3373 select {
3374 case *respChan <- nil:
3375 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3376 default:
3377 }
3378 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003379 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003380}
3381
Himani Chawla26e555c2020-08-31 12:30:20 +05303382// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003383// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003384// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003385func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003386 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 +00003387 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003388
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003389 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003390 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003391 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3392 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003393 }
3394
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003395 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3396 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003397 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003398 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003399 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3400 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003401 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3402 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003403 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003404 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3405 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003406 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3407 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003408 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003409 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303410 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003411 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003412 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3413 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003414 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003415 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003416 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3417 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003418 }
3419 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003420 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003421 "device-id": dh.DeviceID})
3422 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003423 }
3424 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003425 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003426 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3427 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003428 }
3429 return nil
3430}
3431
mpagenkofc4f56e2020-11-04 17:17:49 +00003432//VerifyVlanConfigRequest checks on existence of a given uniPort
3433// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003434func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003435 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003436 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003437 for _, uniPort := range dh.uniEntityMap {
3438 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003439 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003440 pCurrentUniPort = uniPort
3441 break //found - end search loop
3442 }
3443 }
3444 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003445 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003446 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003447 return
3448 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003449 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003450}
3451
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003452//VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
3453func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003454 //TODO!! verify and start pending flow configuration
3455 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3456 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003457
3458 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003459 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003460 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003461 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003462 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003463 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003464 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003465 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003466 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3467 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003468 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003469 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003470 } else {
3471 /***** UniVlanConfigFsm continued */
3472 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003473 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3474 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003475 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003476 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3477 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003478 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003479 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003480 } else {
3481 /***** UniVlanConfigFsm continued */
3482 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003483 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3484 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003485 }
mpagenkodff5dda2020-08-28 11:52:01 +00003486 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003487 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003488 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3489 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003490 }
3491 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003492 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 +00003493 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3494 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003495 }
3496 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003497 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003498 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003499 }
mpagenkof1fc3862021-02-16 10:09:52 +00003500 } else {
3501 dh.lockVlanConfig.RUnlock()
3502 }
mpagenkodff5dda2020-08-28 11:52:01 +00003503}
3504
3505//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3506// 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 +00003507func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003508 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003509 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003510 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003511 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003512 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003513 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003514}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003515
mpagenkof1fc3862021-02-16 10:09:52 +00003516//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003517func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003518 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3519 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3520 // obviously then parallel processing on the cancel must be avoided
3521 // deadline context to ensure completion of background routines waited for
3522 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3523 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3524 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3525
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003526 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003527 var wg sync.WaitGroup
3528 wg.Add(1) // for the 1 go routine to finish
3529
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003530 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003531 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3532
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003533 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003534}
3535
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003536//StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003537//available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003538func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3539 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003540
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003541 if dh.IsReconciling() {
3542 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003543 return nil
3544 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003545 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003546
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003547 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003548 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003549 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3550 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003551 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003552 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003553
mpagenkof1fc3862021-02-16 10:09:52 +00003554 if aWriteToKvStore {
3555 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3556 }
3557 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003558}
3559
dbainbri4d3a0dc2020-12-02 00:33:42 +00003560func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003561 defer cancel() //ensure termination of context (may be pro forma)
3562 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003563 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003564 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003565}
3566
mpagenkoe4782082021-11-25 12:04:26 +00003567//ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
3568// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
3569func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
3570 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
3571 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
3572 dh.mutexDeviceReason.Lock()
3573 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003574 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003575 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003576 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003577 DeviceId: dh.DeviceID,
3578 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003579 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00003580 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003581 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003582 return err
3583 }
mpagenkoe4782082021-11-25 12:04:26 +00003584 } else {
3585 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 +00003586 }
mpagenkoe4782082021-11-25 12:04:26 +00003587 dh.deviceReason = deviceReason
3588 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
3589 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003590 return nil
3591}
3592
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003593func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3594 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003595 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003596 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3597 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003598 }
mpagenkof1fc3862021-02-16 10:09:52 +00003599 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003600}
3601
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003602// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003603// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003604func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3605 dh.lockDevice.RLock()
3606 defer dh.lockDevice.RUnlock()
3607 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003608 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003609 }
3610 return 0, errors.New("error-fetching-uni-port")
3611}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003612
3613// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003614func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3615 var errorsList []error
3616 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 -08003617
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003618 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3619 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3620 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3621
3622 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3623 // successfully.
3624 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3625 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3626 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003627 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 -08003628 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003629 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003630 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003631 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003632}
3633
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003634func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3635 var err error
3636 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003637 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003638
3639 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003640 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003641 errorsList = append(errorsList, err)
3642 }
3643 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003644 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003645
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003646 return errorsList
3647}
3648
3649func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3650 var err error
3651 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003652 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003653 // Check if group metric related config is updated
3654 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003655 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3656 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3657 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003658
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003659 if ok && m.Frequency != v.GroupFreq {
3660 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003661 errorsList = append(errorsList, err)
3662 }
3663 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003664 if ok && m.Enabled != v.Enabled {
3665 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003666 errorsList = append(errorsList, err)
3667 }
3668 }
3669 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003670 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003671 return errorsList
3672}
3673
3674func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3675 var err error
3676 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003677 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003678 // Check if standalone metric related config is updated
3679 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003680 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3681 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3682 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003683
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003684 if ok && m.Frequency != v.SampleFreq {
3685 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003686 errorsList = append(errorsList, err)
3687 }
3688 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003689 if ok && m.Enabled != v.Enabled {
3690 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003691 errorsList = append(errorsList, err)
3692 }
3693 }
3694 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003695 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003696 return errorsList
3697}
3698
3699// nolint: gocyclo
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003700func (dh *deviceHandler) StartCollector(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003701 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08003702
3703 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003704 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303705 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003706 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003707 // Initialize the next metric collection time.
3708 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3709 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003710 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003711 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003712 for {
3713 select {
3714 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003715 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003716 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003717 // Stop the L2 PM FSM
3718 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003719 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3720 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3721 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003722 }
3723 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003724 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003725 }
3726 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003727 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3728 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003729 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003730 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3731 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003732 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003733
Girish Gowdrae09a6202021-01-12 18:10:59 -08003734 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003735 case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3736 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3737 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3738 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3739 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003740 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003741 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003742 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003743 } else {
3744 if dh.pmConfigs.Grouped { // metrics are managed as a group
3745 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003746 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003747
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003748 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3749 // 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 -08003750 // 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 +00003751 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3752 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003753 }
3754 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003755 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3756 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3757 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3758 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003759 }
3760 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003761 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003762
3763 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003764 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3765 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3766 // 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 -08003767 // 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 +00003768 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3769 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003770 }
3771 }
3772 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003773 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3774 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3775 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3776 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003777 }
3778 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003779 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003780 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003781 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003782 } */
3783 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003784 }
3785 }
3786}
kesavandfdf77632021-01-26 23:40:33 -05003787
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003788func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003789
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003790 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3791 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003792}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003793
Himani Chawla43f95ff2021-06-03 00:24:12 +05303794func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3795 if dh.pOnuMetricsMgr == nil {
3796 return &extension.SingleGetValueResponse{
3797 Response: &extension.GetValueResponse{
3798 Status: extension.GetValueResponse_ERROR,
3799 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3800 },
3801 }
3802 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303803 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303804 return resp
3805}
3806
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003807func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3808 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003809 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003810 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003811 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003812}
3813
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003814func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003815 var pAdapterFsm *cmn.AdapterFsm
3816 //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 +00003817 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003818 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003819 {
mpagenkofbf577d2021-10-12 11:44:33 +00003820 if dh.pOnuOmciDevice != nil {
3821 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3822 } else {
3823 return true //FSM not active - so there is no activity on omci
3824 }
mpagenkof1fc3862021-02-16 10:09:52 +00003825 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003826 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003827 {
mpagenkofbf577d2021-10-12 11:44:33 +00003828 if dh.pOnuOmciDevice != nil {
3829 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3830 } else {
3831 return true //FSM not active - so there is no activity on omci
3832 }
mpagenkof1fc3862021-02-16 10:09:52 +00003833 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003834 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003835 {
mpagenkofbf577d2021-10-12 11:44:33 +00003836 if dh.pLockStateFsm != nil {
3837 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3838 } else {
3839 return true //FSM not active - so there is no activity on omci
3840 }
mpagenkof1fc3862021-02-16 10:09:52 +00003841 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003842 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003843 {
mpagenkofbf577d2021-10-12 11:44:33 +00003844 if dh.pUnlockStateFsm != nil {
3845 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3846 } else {
3847 return true //FSM not active - so there is no activity on omci
3848 }
mpagenkof1fc3862021-02-16 10:09:52 +00003849 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003850 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003851 {
mpagenkofbf577d2021-10-12 11:44:33 +00003852 if dh.pOnuMetricsMgr != nil {
3853 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003854 } else {
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 +00003858 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003859 {
3860 dh.lockUpgradeFsm.RLock()
3861 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003862 if dh.pOnuUpradeFsm != nil {
3863 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3864 } else {
3865 return true //FSM not active - so there is no activity on omci
3866 }
mpagenko80622a52021-02-09 16:53:23 +00003867 }
mpagenkof1fc3862021-02-16 10:09:52 +00003868 default:
3869 {
3870 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003871 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003872 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003873 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003874 }
mpagenkofbf577d2021-10-12 11:44:33 +00003875 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3876 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3877 }
3878 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003879}
3880
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003881func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3882 for _, v := range dh.pOnuTP.PAniConfigFsm {
3883 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003884 return false
3885 }
3886 }
3887 return true
3888}
3889
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003890func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003891 dh.lockVlanConfig.RLock()
3892 defer dh.lockVlanConfig.RUnlock()
3893 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003894 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003895 return false
3896 }
3897 }
3898 return true //FSM not active - so there is no activity on omci
3899}
3900
3901func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3902 dh.lockVlanConfig.RLock()
3903 defer dh.lockVlanConfig.RUnlock()
3904 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003905 if v.PAdaptFsm.PFsm != nil {
3906 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003907 return true //there is at least one VLAN FSM with some active configuration
3908 }
3909 }
3910 }
3911 return false //there is no VLAN FSM with some active configuration
3912}
3913
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003914func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003915 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3916 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3917 return false
3918 }
3919 }
3920 // a further check is done to identify, if at least some data traffic related configuration exists
3921 // 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])
3922 return dh.checkUserServiceExists(ctx)
3923}
3924
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003925func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003926 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3927 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003928 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003929 // TODO: fatal error reset ONU, delete deviceHandler!
3930 return
3931 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003932 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
3933 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003934}
3935
3936func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3937 dh.mutexCollectorFlag.Lock()
3938 dh.collectorIsRunning = flagValue
3939 dh.mutexCollectorFlag.Unlock()
3940}
3941
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003942func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003943 dh.mutexCollectorFlag.RLock()
3944 flagValue := dh.collectorIsRunning
3945 dh.mutexCollectorFlag.RUnlock()
3946 return flagValue
3947}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303948
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303949func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3950 dh.mutextAlarmManagerFlag.Lock()
3951 dh.alarmManagerIsRunning = flagValue
3952 dh.mutextAlarmManagerFlag.Unlock()
3953}
3954
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003955func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303956 dh.mutextAlarmManagerFlag.RLock()
3957 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003958 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303959 dh.mutextAlarmManagerFlag.RUnlock()
3960 return flagValue
3961}
3962
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003963func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003964 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303965
3966 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003967 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303968 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303969 if stop := <-dh.stopAlarmManager; stop {
3970 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303971 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303972 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003973 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
3974 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05303975 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303976 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003977 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
3978 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05303979 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303980 }
3981}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003982
Girish Gowdrae95687a2021-09-08 16:30:58 -07003983func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
3984 dh.mutexFlowMonitoringRoutineFlag.Lock()
3985 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003986 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003987 dh.isFlowMonitoringRoutineActive[uniID] = flag
3988}
3989
3990func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
3991 dh.mutexFlowMonitoringRoutineFlag.RLock()
3992 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
3993 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003994 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003995 return dh.isFlowMonitoringRoutineActive[uniID]
3996}
3997
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003998func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
3999 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004000
Maninder7961d722021-06-16 22:10:28 +05304001 connectStatus := voltha.ConnectStatus_UNREACHABLE
4002 operState := voltha.OperStatus_UNKNOWN
4003
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004004 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004005 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004006 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004007 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004008 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004009 case success := <-dh.chReconcilingFinished:
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004010 logger.Debugw(ctx, "reconciling finished signal received",
4011 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4012 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4013 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4014 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4015 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4016 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4017 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4018 // However, a later refactoring of the functionality remains unaffected.
4019 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004020 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004021 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304022 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004023 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05304024 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00004025 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004026 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05304027 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004028 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4029 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304030 operState = voltha.OperStatus_ACTIVE
4031 } else {
4032 operState = voltha.OperStatus_ACTIVATING
4033 }
4034 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004035 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4036 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4037 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304038 operState = voltha.OperStatus_DISCOVERED
4039 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004040 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004041 logger.Debugw(ctx, "Core DeviceStateUpdate",
4042 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304043 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004044 logger.Debugw(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004045 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004046 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004047 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004048 ConnStatus: connectStatus,
4049 OperStatus: operState,
4050 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304051 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004052 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304053 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004054 } else {
Maninderb5187552021-03-23 22:23:42 +05304055 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004056 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304057
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004058 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304059 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004060 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004061 } else {
4062 onuDevEntry.MutexPersOnuConfig.RLock()
4063 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4064 connectStatus = voltha.ConnectStatus_REACHABLE
4065 }
4066 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304067 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004068 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004069 }
mpagenko101ac942021-11-16 15:01:29 +00004070 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004071 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004072 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004073 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304074
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004075 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304076 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004077 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004078 } else {
4079 onuDevEntry.MutexPersOnuConfig.RLock()
4080 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4081 connectStatus = voltha.ConnectStatus_REACHABLE
4082 }
4083 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304084 }
4085
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004086 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304087
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004088 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004089 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004090 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004091 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004092 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004093
4094 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4095 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4096 } else {
4097 onuDevEntry.MutexReconciledTpInstances.Lock()
4098 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
4099 onuDevEntry.MutexReconciledTpInstances.Unlock()
4100 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004101 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004102 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004103 dh.mutexReconcilingFlag.Lock()
4104 if skipOnuConfig {
4105 dh.reconciling = cSkipOnuConfigReconciling
4106 } else {
4107 dh.reconciling = cOnuConfigReconciling
4108 }
4109 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004110}
4111
mpagenko101ac942021-11-16 15:01:29 +00004112func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004113 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
4114 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004115 dh.sendChReconcileFinished(success)
4116 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4117 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4118 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004119 } else {
mpagenko101ac942021-11-16 15:01:29 +00004120 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004121 }
4122}
4123
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004124func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004125 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004126 defer dh.mutexReconcilingFlag.RUnlock()
4127 return dh.reconciling != cNoReconciling
4128}
4129
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004130func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004131 dh.mutexReconcilingFlag.RLock()
4132 defer dh.mutexReconcilingFlag.RUnlock()
4133 return dh.reconciling == cSkipOnuConfigReconciling
4134}
4135
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004136func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4137 dh.mutexReconcilingFirstPassFlag.Lock()
4138 dh.reconcilingFirstPass = value
4139 dh.mutexReconcilingFirstPassFlag.Unlock()
4140}
4141
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004142func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4143 dh.mutexReconcilingReasonUpdate.Lock()
4144 dh.reconcilingReasonUpdate = value
4145 dh.mutexReconcilingReasonUpdate.Unlock()
4146}
4147
4148func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4149 dh.mutexReconcilingReasonUpdate.RLock()
4150 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4151 return dh.reconcilingReasonUpdate
4152}
4153
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004154func (dh *deviceHandler) getDeviceReason() uint8 {
4155 dh.mutexDeviceReason.RLock()
4156 value := dh.deviceReason
4157 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004158 return value
4159}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004160
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004161func (dh *deviceHandler) GetDeviceReasonString() string {
4162 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004163}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004164
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004165func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004166 dh.mutexReadyForOmciConfig.Lock()
4167 dh.readyForOmciConfig = flagValue
4168 dh.mutexReadyForOmciConfig.Unlock()
4169}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004170func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004171 dh.mutexReadyForOmciConfig.RLock()
4172 flagValue := dh.readyForOmciConfig
4173 dh.mutexReadyForOmciConfig.RUnlock()
4174 return flagValue
4175}
Maninder7961d722021-06-16 22:10:28 +05304176
4177func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004178 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304179 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004180 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304181 }
4182
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004183 logger.Debugw(ctx, "Core DeviceStateUpdate",
4184 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004185 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004186 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004187 ConnStatus: connectStatus,
4188 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4189 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304190 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004191 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304192 }
4193}
khenaidoo7d3c5582021-08-11 18:09:44 -04004194
4195/*
4196Helper functions to communicate with Core
4197*/
4198
4199func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4200 cClient, err := dh.coreClient.GetCoreServiceClient()
4201 if err != nil || cClient == nil {
4202 return nil, err
4203 }
4204 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4205 defer cancel()
4206 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4207 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4208}
4209
khenaidoo42dcdfd2021-10-19 17:34:12 -04004210func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004211 cClient, err := dh.coreClient.GetCoreServiceClient()
4212 if err != nil || cClient == nil {
4213 return err
4214 }
4215 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4216 defer cancel()
4217 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004218 logger.Debugw(subCtx, "device-updated-in-core",
4219 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004220 return err
4221}
4222
4223func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4224 cClient, err := dh.coreClient.GetCoreServiceClient()
4225 if err != nil || cClient == nil {
4226 return err
4227 }
4228 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4229 defer cancel()
4230 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004231 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4232 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004233 return err
4234}
4235
4236func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4237 cClient, err := dh.coreClient.GetCoreServiceClient()
4238 if err != nil || cClient == nil {
4239 return err
4240 }
4241 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4242 defer cancel()
4243 _, err = cClient.DeviceUpdate(subCtx, device)
4244 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4245 return err
4246}
4247
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004248func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004249 cClient, err := dh.coreClient.GetCoreServiceClient()
4250 if err != nil || cClient == nil {
4251 return err
4252 }
4253 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4254 defer cancel()
4255 _, err = cClient.PortCreated(subCtx, port)
4256 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4257 return err
4258}
4259
khenaidoo42dcdfd2021-10-19 17:34:12 -04004260func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004261 cClient, err := dh.coreClient.GetCoreServiceClient()
4262 if err != nil || cClient == nil {
4263 return err
4264 }
4265 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4266 defer cancel()
4267 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004268 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 -04004269 return err
4270}
4271
khenaidoo42dcdfd2021-10-19 17:34:12 -04004272func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004273 cClient, err := dh.coreClient.GetCoreServiceClient()
4274 if err != nil || cClient == nil {
4275 return err
4276 }
4277 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4278 defer cancel()
4279 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004280 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 -04004281 return err
4282}
4283
4284/*
4285Helper functions to communicate with parent adapter
4286*/
4287
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004288func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4289 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4290
4291 var request = ia.TechProfileInstanceRequestMessage{
4292 DeviceId: dh.DeviceID,
4293 TpInstancePath: aTpPath,
4294 ParentDeviceId: dh.parentID,
4295 ParentPonPort: dh.device.ParentPortNo,
4296 OnuId: dh.device.ProxyAddress.OnuId,
4297 UniId: uint32(aUniID),
4298 }
4299
4300 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004301 if err != nil || pgClient == nil {
4302 return nil, err
4303 }
4304 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4305 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004306 logger.Debugw(subCtx, "get-tech-profile-instance",
4307 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004308 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004309}
4310
Girish Gowdrae95687a2021-09-08 16:30:58 -07004311// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4312// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4313func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4314 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4315 dh.setFlowMonitoringIsRunning(uniID, true)
4316 for {
4317 select {
4318 // block on the channel to receive an incoming flow
4319 // process the flow completely before proceeding to handle the next flow
4320 case flowCb := <-dh.flowCbChan[uniID]:
4321 startTime := time.Now()
4322 logger.Debugw(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
4323 respChan := make(chan error)
4324 if flowCb.addFlow {
4325 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4326 } else {
4327 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4328 }
4329 // Block on response and tunnel it back to the caller
4330 *flowCb.respChan <- <-respChan
4331 logger.Debugw(flowCb.ctx, "serial-flow-processor--end",
4332 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4333 case <-dh.stopFlowMonitoringRoutine[uniID]:
4334 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4335 dh.setFlowMonitoringIsRunning(uniID, false)
4336 return
4337 }
4338 }
4339}
4340
khenaidoo42dcdfd2021-10-19 17:34:12 -04004341func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004342 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4343 if err != nil || pgClient == nil {
4344 return err
4345 }
4346 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4347 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004348 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004349 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4350 if err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004351 logger.Errorw(ctx, "omci-failure",
4352 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
4353 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
khenaidoo7d3c5582021-08-11 18:09:44 -04004354 }
4355 return err
4356}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004357
4358// GetDeviceID - TODO: add comment
4359func (dh *deviceHandler) GetDeviceID() string {
4360 return dh.DeviceID
4361}
4362
4363// GetProxyAddressID - TODO: add comment
4364func (dh *deviceHandler) GetProxyAddressID() string {
4365 return dh.device.ProxyAddress.GetDeviceId()
4366}
4367
4368// GetProxyAddressType - TODO: add comment
4369func (dh *deviceHandler) GetProxyAddressType() string {
4370 return dh.device.ProxyAddress.GetDeviceType()
4371}
4372
4373// GetProxyAddress - TODO: add comment
4374func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4375 return dh.device.ProxyAddress
4376}
4377
4378// GetEventProxy - TODO: add comment
4379func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4380 return dh.EventProxy
4381}
4382
4383// GetOmciTimeout - TODO: add comment
4384func (dh *deviceHandler) GetOmciTimeout() int {
4385 return dh.pOpenOnuAc.omciTimeout
4386}
4387
4388// GetAlarmAuditInterval - TODO: add comment
4389func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4390 return dh.pOpenOnuAc.alarmAuditInterval
4391}
4392
4393// GetDlToOnuTimeout4M - TODO: add comment
4394func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4395 return dh.pOpenOnuAc.dlToOnuTimeout4M
4396}
4397
4398// GetUniEntityMap - TODO: add comment
4399func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4400 return &dh.uniEntityMap
4401}
4402
4403// GetPonPortNumber - TODO: add comment
4404func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4405 return &dh.ponPortNumber
4406}
4407
4408// GetUniVlanConfigFsm - TODO: add comment
4409func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004410 dh.lockVlanConfig.RLock()
4411 value := dh.UniVlanConfigFsmMap[uniID]
4412 dh.lockVlanConfig.RUnlock()
4413 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004414}
4415
4416// GetOnuAlarmManager - TODO: add comment
4417func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4418 return dh.pAlarmMgr
4419}
4420
4421// GetOnuMetricsManager - TODO: add comment
4422func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4423 return dh.pOnuMetricsMgr
4424}
4425
4426// GetOnuTP - TODO: add comment
4427func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4428 return dh.pOnuTP
4429}
4430
4431// GetBackendPathPrefix - TODO: add comment
4432func (dh *deviceHandler) GetBackendPathPrefix() string {
4433 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4434}
4435
4436// GetOnuIndication - TODO: add comment
4437func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4438 return dh.pOnuIndication
4439}
4440
4441// RLockMutexDeletionInProgressFlag - TODO: add comment
4442func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4443 dh.mutexDeletionInProgressFlag.RLock()
4444}
4445
4446// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4447func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4448 dh.mutexDeletionInProgressFlag.RUnlock()
4449}
4450
4451// GetDeletionInProgress - TODO: add comment
4452func (dh *deviceHandler) GetDeletionInProgress() bool {
4453 return dh.deletionInProgress
4454}
4455
4456// GetPmConfigs - TODO: add comment
4457func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4458 return dh.pmConfigs
4459}
4460
4461// GetDeviceType - TODO: add comment
4462func (dh *deviceHandler) GetDeviceType() string {
4463 return dh.DeviceType
4464}
4465
4466// GetLogicalDeviceID - TODO: add comment
4467func (dh *deviceHandler) GetLogicalDeviceID() string {
4468 return dh.logicalDeviceID
4469}
4470
4471// GetDevice - TODO: add comment
4472func (dh *deviceHandler) GetDevice() *voltha.Device {
4473 return dh.device
4474}
4475
4476// GetMetricsEnabled - TODO: add comment
4477func (dh *deviceHandler) GetMetricsEnabled() bool {
4478 return dh.pOpenOnuAc.MetricsEnabled
4479}
4480
4481// InitPmConfigs - TODO: add comment
4482func (dh *deviceHandler) InitPmConfigs() {
4483 dh.pmConfigs = &voltha.PmConfigs{}
4484}
4485
4486// GetUniPortMask - TODO: add comment
4487func (dh *deviceHandler) GetUniPortMask() int {
4488 return dh.pOpenOnuAc.config.UniPortMask
4489}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00004490
4491func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
4492 tpPathFound := false
4493 for _, tpPath := range aTpPathMap {
4494 if tpPath != "" {
4495 tpPathFound = true
4496 }
4497 }
4498 return tpPathFound
4499}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004500
4501// PrepareForGarbageCollection - remove references to prepare for garbage collection
4502func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
4503 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
4504
4505 // Note: This function must be called as a goroutine to prevent blocking of further processing!
4506 // first let the objects rest for some time to give all asynchronously started
4507 // cleanup routines a chance to come to an end
4508 time.Sleep(5 * time.Second)
4509
4510 if dh.pOnuTP != nil {
4511 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
4512 }
4513 if dh.pOnuMetricsMgr != nil {
4514 dh.pOnuMetricsMgr.PrepareForGarbageCollection(ctx, aDeviceID)
4515 }
4516 if dh.pAlarmMgr != nil {
4517 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
4518 }
4519 if dh.pSelfTestHdlr != nil {
4520 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
4521 }
4522 if dh.pLockStateFsm != nil {
4523 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4524 }
4525 if dh.pUnlockStateFsm != nil {
4526 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4527 }
4528 if dh.pOnuUpradeFsm != nil {
4529 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4530 }
4531 if dh.pOnuOmciDevice != nil {
4532 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
4533 }
4534 for k, v := range dh.UniVlanConfigFsmMap {
4535 v.PrepareForGarbageCollection(ctx, aDeviceID)
4536 delete(dh.UniVlanConfigFsmMap, k)
4537 }
4538 dh.pOnuOmciDevice = nil
4539 dh.pOnuTP = nil
4540 dh.pOnuMetricsMgr = nil
4541 dh.pAlarmMgr = nil
4542 dh.pSelfTestHdlr = nil
4543 dh.pLockStateFsm = nil
4544 dh.pUnlockStateFsm = nil
4545 dh.pOnuUpradeFsm = nil
4546}