blob: f74da5a44a72e768a0621dd37603e17c822362f4 [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
225 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
226 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000227}
228
Himani Chawla6d2ae152020-09-02 13:11:20 +0530229//newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400230func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530231 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400232 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000233 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400234 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000235 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000236 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000237 dh.DeviceType = cloned.Type
238 dh.adminState = "up"
239 dh.device = cloned
240 dh.pOpenOnuAc = adapter
241 dh.exitChannel = make(chan int, 1)
242 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000243 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000244 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000245 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530246 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530247 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000248 dh.stopHeartbeatCheck = make(chan bool, 2)
249 //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 +0000250 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000251 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000252 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000253 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000254 dh.lockUpgradeFsm = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000255 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000256 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000257 dh.reconcilingReasonUpdate = false
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000258 dh.reconcilingFirstPass = true
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000259 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000260 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
261 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
262 if rECSeconds < 2 {
263 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
264 rECSeconds = 2
265 }
266 rEVCSeconds := rECSeconds / 2
267 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000268 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000269 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000270 dh.pLastUpgradeImageState = &voltha.ImageState{
271 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
272 Reason: voltha.ImageState_UNKNOWN_ERROR,
273 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
274 }
275 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000276
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800277 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
278 dh.pmConfigs = cloned.PmConfigs
279 } /* else {
280 // will be populated when onu_metrics_mananger is initialized.
281 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800282
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000283 // Device related state machine
284 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000285 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000287 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
288 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
289 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
290 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
291 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000292 },
293 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000294 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
295 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
296 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
297 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
298 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
299 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
300 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
301 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000302 },
303 )
mpagenkoaf801632020-07-03 10:00:42 +0000304
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000305 return &dh
306}
307
Himani Chawla6d2ae152020-09-02 13:11:20 +0530308// start save the device to the data model
309func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000310 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000311 // Add the initial device to the local model
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000312 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000313}
314
Himani Chawla4d908332020-08-31 12:30:20 +0530315/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000316// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530317func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000318 logger.Debug("stopping-device-handler")
319 dh.exitChannel <- 1
320}
Himani Chawla4d908332020-08-31 12:30:20 +0530321*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000322
323// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530324// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000325
Girish Gowdrae0140f02021-02-02 16:55:09 -0800326//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530327func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400328 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000329
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000330 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000331 if dh.pDeviceStateFsm.Is(devStNull) {
332 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000333 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 +0000334 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000335 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800336 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
337 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800338 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400339 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000340 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800341 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800342 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000343 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000344 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000345 }
346
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000347}
348
khenaidoo42dcdfd2021-10-19 17:34:12 -0400349func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000350 /* 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 +0530351 //assuming omci message content is hex coded!
352 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000353 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000354 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000355 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000356 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530357 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000358 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000359 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000360 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000361 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
362 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530363 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000364 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
365 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530366}
367
khenaidoo42dcdfd2021-10-19 17:34:12 -0400368func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000369 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000370
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000371 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000372 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000373 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
374 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000375 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530376 if dh.pOnuTP == nil {
377 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000378 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000379 log.Fields{"device-id": dh.DeviceID})
380 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530381 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000382 if !dh.IsReadyForOmciConfig() {
383 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
384 "device-state": dh.GetDeviceReasonString()})
385 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530386 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000387 //previous state test here was just this one, now extended for more states to reject the SetRequest:
388 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
389 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530390
Himani Chawla26e555c2020-08-31 12:30:20 +0530391 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000392 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
393 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000394 dh.pOnuTP.LockTpProcMutex()
395 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000396
mpagenko44bd8362021-11-15 11:40:05 +0000397 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000398 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000399 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000400 }
401 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000402 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800403 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700404 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800405 return err
406 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000407 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
408 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000409
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000410 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530411
Girish Gowdra50e56422021-06-01 16:46:04 -0700412 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400413 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000414 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
415 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700416 // if there has been some change for some uni TechProfilePath
417 //in order to allow concurrent calls to other dh instances we do not wait for execution here
418 //but doing so we can not indicate problems to the caller (who does what with that then?)
419 //by now we just assume straightforward successful execution
420 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
421 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530422
Girish Gowdra50e56422021-06-01 16:46:04 -0700423 // deadline context to ensure completion of background routines waited for
424 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
425 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
426 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000427
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000428 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700429
430 var wg sync.WaitGroup
431 wg.Add(1) // for the 1 go routine to finish
432 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000433 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700434 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000435 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
436 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 -0700437 return tpErr
438 }
439 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
440 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000441 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700442 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000443 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700444 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000445 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
446 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 -0700447 return kvErr
448 }
449 return nil
450 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000451 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700452 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700453 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530454 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000455 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000456 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
457 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530458 return nil
459}
460
khenaidoo42dcdfd2021-10-19 17:34:12 -0400461func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000462 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530463
464 if dh.pOnuTP == nil {
465 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000466 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000467 log.Fields{"device-id": dh.DeviceID})
468 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530469 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530470 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000471 dh.pOnuTP.LockTpProcMutex()
472 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530473
mpagenko0f543222021-11-03 16:24:14 +0000474 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
475 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
476 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000477 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000478 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000479 }
480 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000481 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800482 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000483 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
484 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800485 return err
486 }
mpagenko0f543222021-11-03 16:24:14 +0000487 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
488 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000489 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000490
Mahir Gunyel9545be22021-07-04 15:53:16 -0700491 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000492 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000493
Himani Chawla26e555c2020-08-31 12:30:20 +0530494}
495
khenaidoo42dcdfd2021-10-19 17:34:12 -0400496func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000497 logger.Infow(ctx, "delete-tcont-request start", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000498
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000499 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000500 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000501 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
502 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000503 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530504 if dh.pOnuTP == nil {
505 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000506 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000507 log.Fields{"device-id": dh.DeviceID})
508 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530509 }
510
Himani Chawla26e555c2020-08-31 12:30:20 +0530511 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000512 dh.pOnuTP.LockTpProcMutex()
513 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000514
mpagenko0f543222021-11-03 16:24:14 +0000515 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
516 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
517 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000518 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000519 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000520 }
521 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700522 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000523 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800524 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000525 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
526 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800527 return err
528 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000529 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "tcont": delTcontMsg.AllocId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000530
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000531 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530532
Mahir Gunyel9545be22021-07-04 15:53:16 -0700533 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000534 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000535
Mahir Gunyel9545be22021-07-04 15:53:16 -0700536}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000537
Mahir Gunyel9545be22021-07-04 15:53:16 -0700538func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000539 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
540 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700541 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000542 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
543 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530544 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700545 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000546 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700547 resourceName = "Gem"
548 } else {
549 resourceName = "Tcont"
550 }
551
552 // deadline context to ensure completion of background routines waited for
553 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
554 dctx, cancel := context.WithDeadline(context.Background(), deadline)
555
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000556 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700557
558 var wg sync.WaitGroup
559 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000560 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700561 resource, entryID, &wg)
562 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000563 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
564 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700565 return err
566 }
567
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000568 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
569 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
570 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
571 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700572 var wg2 sync.WaitGroup
573 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
574 wg2.Add(1)
575 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000576 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
577 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700578 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000579 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
580 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700581 return err
582 }
583 }
584 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000585 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700586 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530587 return nil
588}
589
mpagenkodff5dda2020-08-28 11:52:01 +0000590//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000591func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400592 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400593 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700594 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
595 var errorsList []error
596 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000597 //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 +0000598 if apOfFlowChanges.ToRemove != nil {
599 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000600 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000601 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000602 "device-id": dh.DeviceID})
603 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700604 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000605 continue
606 }
607 flowInPort := flow.GetInPort(flowItem)
608 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000609 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
610 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700611 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000612 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000613 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000614 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000615 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000616 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000617 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000618 continue
619 } else {
620 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000621 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000622 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
623 loUniPort = uniPort
624 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000625 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000626 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000627 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000628 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700629 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000630 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000631 }
632 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000633 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000634 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
635 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700636
637 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
638 // Step1 : Fill flowControlBlock
639 // Step2 : Push the flowControlBlock to ONU channel
640 // Step3 : Wait on response channel for response
641 // Step4 : Return error value
642 startTime := time.Now()
643 respChan := make(chan error)
644 flowCb := FlowCb{
645 ctx: ctx,
646 addFlow: false,
647 flowItem: flowItem,
648 flowMetaData: nil,
649 uniPort: loUniPort,
650 respChan: &respChan,
651 }
652 dh.flowCbChan[loUniPort.UniID] <- flowCb
653 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
654 // Wait on the channel for flow handlers return value
655 retError = <-respChan
656 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
657 if retError != nil {
658 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
659 log.Fields{"device-id": dh.DeviceID, "error": retError})
660 errorsList = append(errorsList, retError)
661 continue
662 }
663 } else {
664 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
665 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000666 }
667 }
668 }
669 }
mpagenko01e726e2020-10-23 09:45:29 +0000670 if apOfFlowChanges.ToAdd != nil {
671 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
672 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000673 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000674 "device-id": dh.DeviceID})
675 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700676 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000677 continue
678 }
679 flowInPort := flow.GetInPort(flowItem)
680 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000681 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
682 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700683 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000684 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000685 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000686 } else if flowInPort == dh.ponPortNumber {
687 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000688 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000689 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000690 continue
691 } else {
692 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000693 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000694 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
695 loUniPort = uniPort
696 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000697 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000698 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000699 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000700 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700701 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000702 continue
mpagenko01e726e2020-10-23 09:45:29 +0000703 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000704 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
705 // if not, we just throw some error here to have an indication about that, if we really need to support that
706 // then we would need to create some means to activate the internal stored flows
707 // after the device gets active automatically (and still with its dependency to the TechProfile)
708 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
709 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000710 if !dh.IsReadyForOmciConfig() {
711 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
712 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700713 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
714 errorsList = append(errorsList, retError)
715 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000716 }
717
mpagenko01e726e2020-10-23 09:45:29 +0000718 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000719 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000720 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
721 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700722 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
723 // Step1 : Fill flowControlBlock
724 // Step2 : Push the flowControlBlock to ONU channel
725 // Step3 : Wait on response channel for response
726 // Step4 : Return error value
727 startTime := time.Now()
728 respChan := make(chan error)
729 flowCb := FlowCb{
730 ctx: ctx,
731 addFlow: true,
732 flowItem: flowItem,
733 flowMetaData: apFlowMetaData,
734 uniPort: loUniPort,
735 respChan: &respChan,
736 }
737 dh.flowCbChan[loUniPort.UniID] <- flowCb
738 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
739 // Wait on the channel for flow handlers return value
740 retError = <-respChan
741 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
742 if retError != nil {
743 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
744 log.Fields{"device-id": dh.DeviceID, "error": retError})
745 errorsList = append(errorsList, retError)
746 continue
747 }
748 } else {
749 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
750 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000751 }
752 }
753 }
754 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700755 if len(errorsList) > 0 {
756 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
757 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
758 }
759 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000760}
761
Himani Chawla6d2ae152020-09-02 13:11:20 +0530762//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000763//following are the expected device states after this activity:
764//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
765// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000766func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
767 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000768
mpagenko900ee4b2020-10-12 11:56:34 +0000769 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000770 //note that disableDevice sequences in some 'ONU active' state may yield also
771 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000772 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000773 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000774 //disable-device shall be just a UNi/ONU-G related admin state setting
775 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000776
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000777 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000778 // disable UNI ports/ONU
779 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
780 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000781 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000782 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000783 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000784 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000785 }
786 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000787 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000788 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000789 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400790 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000791 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000792 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400793 OperStatus: voltha.OperStatus_UNKNOWN,
794 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000795 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000796 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000797 }
mpagenko01e726e2020-10-23 09:45:29 +0000798 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000799
800 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000801 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000802 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300803 }
804}
805
Himani Chawla6d2ae152020-09-02 13:11:20 +0530806//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000807func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
808 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000809
mpagenkoaa3afe92021-05-21 16:20:58 +0000810 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000811 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
812 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
813 // for real ONU's that should have nearly no influence
814 // Note that for real ONU's there is anyway a problematic situation with following sequence:
815 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
816 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
817 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000818 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000819
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000820 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000821 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000822 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000823 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000824 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000825 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000826 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000827 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300828}
829
dbainbri4d3a0dc2020-12-02 00:33:42 +0000830func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000831 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000832
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000833 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000834 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000835 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000836 return
837 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000838 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000839 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000840 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000841 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000842 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000843 }
mpagenko101ac942021-11-16 15:01:29 +0000844 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000845 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000846 }
Himani Chawla4d908332020-08-31 12:30:20 +0530847 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000848 pDevEntry.MutexPersOnuConfig.RLock()
849 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
850 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
851 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
852 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
853 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000854 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000855}
856
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000857func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000858 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000859
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000860 continueWithFlowConfig := false
861
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000862 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000863 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000864 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000865 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
866 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000867 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000868 dh.pOnuTP.LockTpProcMutex()
869 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000870
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000871 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000872 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000873 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
874 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000875 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000876 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000877 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
878 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000879 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000880 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700881 techProfsFound := false
882 techProfInstLoadFailed := false
883outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000884 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000885 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000886 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000887 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000888 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000889 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000890 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000891 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000892 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
893 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000894 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000895 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000896 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700897 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000898 var iaTechTpInst ia.TechProfileDownloadMessage
899 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800900 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000901 pDevEntry.MutexReconciledTpInstances.RLock()
902 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
903 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000904 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000905 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700906 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000907 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700908 break outerLoop
909 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000910 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000911 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700912 var tpInst tech_profile.TechProfileInstance
913 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400914 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700915 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000916 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000917 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700918 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000919 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000920 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700921 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
922 break outerLoop
923 }
924
Girish Gowdra041dcb32020-11-16 16:54:30 -0800925 // deadline context to ensure completion of background routines waited for
926 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
927 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000928 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000929
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000930 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800931 var wg sync.WaitGroup
932 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000933 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000934 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000935 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
936 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700937 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
938 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800939 }
mpagenko2dc896e2021-08-02 12:03:59 +0000940 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000941 if len(uniData.PersFlowParams) != 0 {
942 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000943 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000944 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000945 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000946 } // for all UNI entries from SOnuPersistentData
947 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
948 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000949 }
mpagenko2dc896e2021-08-02 12:03:59 +0000950
951 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
952 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000953
954 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +0000955}
956
957func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
958 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
959 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000960 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000961 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000962 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000963 return
964 }
mpagenko2dc896e2021-08-02 12:03:59 +0000965 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000966 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +0000967 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -0700968 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000969 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000970 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000971 }
mpagenko2dc896e2021-08-02 12:03:59 +0000972 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000973 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000974 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000975 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000976 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000977}
978
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000979func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
980 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000981
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000982 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000983 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000984 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000985 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000986 return
987 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000988
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000989 pDevEntry.MutexPersOnuConfig.RLock()
990 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
991 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000992 logger.Debugw(ctx, "reconciling - no uni-configs 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 Hildebrandt3a644642020-12-02 09:46:18 +0000995 return
996 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000997 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +0000998 var uniVlanConfigEntries []uint8
999 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1000
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001001 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001002 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1003 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001004 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001005 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001006 continue
1007 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001008 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001009 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001010 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001011 // It doesn't make sense to configure any flows if no TPs are available
1012 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001013 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001014 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1015 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001016 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001017 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001018
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001019 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001020 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001021 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001022 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001023 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1024 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001025 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001026 return
1027 }
mpagenko101ac942021-11-16 15:01:29 +00001028 //needed to split up function due to sca complexity
1029 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1030
mpagenko2dc896e2021-08-02 12:03:59 +00001031 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001032 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001033 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1034 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001035 // this can't be used as global finished reconciling flag because
1036 // assumes is getting called before the state machines for the last flow is completed,
1037 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001038 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1039 } // for all UNI entries from SOnuPersistentData
1040 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001041
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001042 if !flowsFound {
1043 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001044 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001045 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001046 return
1047 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001048 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1049 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1050 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1051 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1052 log.Fields{"device-id": dh.DeviceID})
1053 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1054 if pDevEntry != nil {
1055 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001056 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001057 } else {
1058 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1059 log.Fields{"device-id": dh.DeviceID})
1060 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1061 if pDevEntry != nil {
1062 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1063 }
1064 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001065 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001066 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001067}
1068
mpagenko101ac942021-11-16 15:01:29 +00001069func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1070 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1071 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1072 flowsProcessed := 0
1073 lastFlowToReconcile := false
1074 loUniID := apUniPort.UniID
1075 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001076 if !(*apFlowsFound) {
1077 *apFlowsFound = true
1078 syncChannel := make(chan struct{})
1079 // start go routine with select() on reconciling vlan config channel before
1080 // starting vlan config reconciling process to prevent loss of any signal
1081 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1082 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1083 //block until the wait routine is really blocked on channel input
1084 // in order to prevent to early ready signal from VlanConfig processing
1085 <-syncChannel
1086 }
1087 if flowsProcessed == len(aPersFlowParam)-1 {
1088 var uniAdded bool
1089 lastFlowToReconcile = true
1090 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1091 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001092 }
1093 }
mpagenko101ac942021-11-16 15:01:29 +00001094 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1095 "device-id": dh.DeviceID, "uni-id": loUniID,
1096 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1097 dh.lockVlanConfig.Lock()
1098 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1099 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1100 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
1101 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1102 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter, nil); err != nil {
1103 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1104 }
1105 } else {
1106 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
1107 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1108 uint8(flowData.VlanRuleParams.SetPcp), cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
1109 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1110 }
1111 }
1112 dh.lockVlanConfig.Unlock()
1113 flowsProcessed++
1114 } //for all flows of this UNI
1115}
1116
1117//waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1118// and decrements the according handler wait group waiting for these indications
1119func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1120 waitGroup *cmn.WaitGroupWithTimeOut) {
1121 var reconciledUniVlanConfigEntries []uint8
1122 var appended bool
1123 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1124 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1125 "device-id": dh.DeviceID, "expiry": expiry})
1126 // indicate blocking on channel now to the caller
1127 aSyncChannel <- struct{}{}
1128 for {
1129 select {
1130 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1131 switch uniIndication {
1132 // no activity requested (should normally not be received) - just continue waiting
1133 case cWaitReconcileFlowNoActivity:
1134 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1135 case cWaitReconcileFlowAbortOnError:
1136 logger.Debugw(ctx, "waitReconcileFlow aborted on error",
1137 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1138 return
1139 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1140 case cWaitReconcileFlowAbortOnSuccess:
1141 logger.Debugw(ctx, "waitReconcileFlow aborted on success",
1142 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1143 return
1144 // this should be a valid UNI vlan config done indication
1145 default:
1146 if uniIndication < platform.MaxUnisPerOnu {
1147 logger.Debugw(ctx, "reconciling flows has been finished in time for this UNI",
1148 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1149 if reconciledUniVlanConfigEntries, appended =
1150 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1151 waitGroup.Done()
1152 }
1153 } else {
1154 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored",
1155 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1156 }
1157 } //switch uniIndication
1158
1159 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1160 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1161 log.Fields{"device-id": dh.DeviceID})
1162 return
1163 }
1164 }
1165}
1166
1167func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1168 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1169}
1170
1171func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1172 for _, ele := range slice {
1173 if ele == val {
1174 return slice, false
1175 }
1176 }
1177 return append(slice, val), true
1178}
1179
1180// sendChReconcileFinished - sends true or false on reconcileFinish channel
1181func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1182 if dh != nil { //if the object still exists (might have been already deleted in background)
1183 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1184 select {
1185 case dh.chReconcilingFinished <- success:
1186 default:
1187 }
1188 }
1189}
1190
1191// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1192func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1193 if dh != nil { //if the object still exists (might have been already deleted in background)
1194 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1195 select {
1196 case dh.chUniVlanConfigReconcilingDone <- value:
1197 default:
1198 }
1199 }
1200}
1201
dbainbri4d3a0dc2020-12-02 00:33:42 +00001202func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001203 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001204
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001205 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001206 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001207 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001208 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001209 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001210 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001211
1212 // deadline context to ensure completion of background routines waited for
1213 //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 +05301214 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001215 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001216
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001217 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001218
1219 var wg sync.WaitGroup
1220 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001221 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001222 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001223
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001224 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001225 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001226}
1227
mpagenko15ff4a52021-03-02 10:09:20 +00001228//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1229// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001230// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001231//was and is called in background - error return does not make sense
1232func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001233 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001234 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001235 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001236 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001237 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001238 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301239 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001240 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001241 return
Himani Chawla4d908332020-08-31 12:30:20 +05301242 }
mpagenko01e726e2020-10-23 09:45:29 +00001243
1244 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001245 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001246
mpagenko44bd8362021-11-15 11:40:05 +00001247 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001248 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001249 // 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 -04001250 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001251 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001252 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001253 OperStatus: voltha.OperStatus_DISCOVERED,
1254 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001255 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001256 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001257 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001258 }
mpagenkoe4782082021-11-25 12:04:26 +00001259 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001260 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001261 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001262 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001263 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1264 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1265 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1266 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001267}
1268
mpagenkoc8bba412021-01-15 15:38:44 +00001269//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001270// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001271func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001272 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001273 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001274 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001275
1276 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001277 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001278 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001279 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1280 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001281 }
1282
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001283 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001284 var inactiveImageID uint16
1285 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1286 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001287 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1288 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001289 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001290 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001291 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001292 if err == nil {
1293 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1294 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001295 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001296 }
1297 } else {
1298 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001299 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001300 }
mpagenko15ff4a52021-03-02 10:09:20 +00001301 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001302 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001303 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001304 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1305 dh.upgradeCanceled = true
1306 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1307 }
mpagenko38662d02021-08-11 09:45:19 +00001308 //no effort spent anymore for the old API to automatically cancel and restart the download
1309 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001310 }
mpagenko15ff4a52021-03-02 10:09:20 +00001311 } else {
1312 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001313 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001314 }
1315 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001316 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1317 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001318 }
1319 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001320}
1321
mpagenkoc26d4c02021-05-06 14:27:57 +00001322//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1323// after the OnuImage has been downloaded to the adapter, called in background
1324func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001325 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001326
1327 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001328 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001329 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001330 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001331 return
1332 }
1333
1334 var inactiveImageID uint16
1335 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1336 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001337 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001338
mpagenko59862f02021-10-11 08:53:18 +00001339 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001340 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001341 // but must be still locked at calling createOnuUpgradeFsm
1342 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1343 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1344 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001345 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1346 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001347 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001348 //flush the remove upgradeFsmChan channel
1349 select {
1350 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001351 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001352 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001353 }
mpagenko59862f02021-10-11 08:53:18 +00001354 dh.lockUpgradeFsm.Unlock()
1355 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1356 dh.upgradeCanceled = true
1357 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1358 }
mpagenko38662d02021-08-11 09:45:19 +00001359 select {
1360 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001361 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001362 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1363 return
1364 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001365 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001366 }
mpagenko59862f02021-10-11 08:53:18 +00001367 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001368 }
mpagenko38662d02021-08-11 09:45:19 +00001369
1370 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001371 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001372 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001373 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001374 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001375 if err == nil {
1376 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1377 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1378 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001379 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001380 return
1381 }
mpagenko38662d02021-08-11 09:45:19 +00001382 } else {
1383 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001384 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001385 }
1386 return
1387 }
1388 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001389 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001390}
1391
1392//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001393func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1394 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001395 var err error
1396 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1397 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1398 // 2.) activation of the inactive image
1399
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001400 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001401 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001402 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1403 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001404 }
1405 dh.lockUpgradeFsm.RLock()
1406 if dh.pOnuUpradeFsm != nil {
1407 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001408 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001409 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001410 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1411 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001412 }
mpagenko59862f02021-10-11 08:53:18 +00001413 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1414 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1415 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1416 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001417 // use the OnuVendor identification from this device for the internal unique name
1418 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001419 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001420 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001421 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001422 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001423 "device-id": dh.DeviceID, "error": err})
1424 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001425 }
mpagenko183647c2021-06-08 15:25:04 +00001426 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001427 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001428 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001429 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001430 } //else
1431 dh.lockUpgradeFsm.RUnlock()
1432
1433 // 2.) check if requested image-version equals the inactive one and start its activation
1434 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1435 var inactiveImageID uint16
1436 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1437 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001438 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1439 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001440 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001441 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001442 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001443 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001444 if err == nil {
1445 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1446 inactiveImageID, aCommitRequest); err != nil {
1447 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001448 "device-id": dh.DeviceID, "error": err})
1449 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001450 }
1451 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001452 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001453 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001454 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001455 } //else
1456 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001457 "device-id": dh.DeviceID, "error": err})
1458 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001459}
1460
1461//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001462func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1463 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001464 var err error
1465 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1466 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1467 // 2.) commitment of the active image
1468
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001469 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001470 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001471 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1472 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001473 }
1474 dh.lockUpgradeFsm.RLock()
1475 if dh.pOnuUpradeFsm != nil {
1476 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001477 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001478 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001479 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1480 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001481 }
mpagenko59862f02021-10-11 08:53:18 +00001482 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1483 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1484 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1485 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001486 // use the OnuVendor identification from this device for the internal unique name
1487 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001488 // 1.) check a started upgrade process and relay the commitment request to it
1489 // the running upgrade may be based either on the imageIdentifier (started from download)
1490 // or on the imageVersion (started from pure activation)
1491 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1492 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001493 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001494 "device-id": dh.DeviceID, "error": err})
1495 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001496 }
mpagenko183647c2021-06-08 15:25:04 +00001497 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001498 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001499 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001500 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001501 } //else
1502 dh.lockUpgradeFsm.RUnlock()
1503
mpagenko183647c2021-06-08 15:25:04 +00001504 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001505 var activeImageID uint16
1506 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1507 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001508 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1509 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001510 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001511 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001512 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001513 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001514 if err == nil {
1515 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1516 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001517 "device-id": dh.DeviceID, "error": err})
1518 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001519 }
1520 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001521 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001522 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001523 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001524 } //else
1525 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001526 "device-id": dh.DeviceID, "error": err})
1527 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001528}
1529
mpagenkoaa3afe92021-05-21 16:20:58 +00001530func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001531 aVersion string) *voltha.ImageState {
1532 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001533 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001534 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001535 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001536 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1537 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1538 if aVersion == dh.pLastUpgradeImageState.Version {
1539 pImageState = dh.pLastUpgradeImageState
1540 } else { //state request for an image version different from last processed image version
1541 pImageState = &voltha.ImageState{
1542 Version: aVersion,
1543 //we cannot state something concerning this version
1544 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1545 Reason: voltha.ImageState_NO_ERROR,
1546 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1547 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001548 }
1549 }
mpagenko38662d02021-08-11 09:45:19 +00001550 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001551}
1552
1553func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1554 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001555 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001556 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001557 dh.lockUpgradeFsm.RLock()
1558 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001559 dh.lockUpgradeFsm.RUnlock()
1560 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001561 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001562 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1563 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1564 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1565 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1566 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1567 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001568 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1569 dh.upgradeCanceled = true
1570 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1571 }
mpagenko45586762021-10-01 08:30:22 +00001572 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001573 } else {
mpagenko45586762021-10-01 08:30:22 +00001574 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001575 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1576 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1577 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1578 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1579 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1580 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001581 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1582 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001583 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1584 //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 +00001585 }
1586}
1587
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001588func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1589
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001590 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001591
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001592 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001593 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001594 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1595 pDevEntry.MutexOnuImageStatus.Lock()
1596 pDevEntry.POnuImageStatus = onuImageStatus
1597 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001598
1599 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001600 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001601 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1602 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001603 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1604 pDevEntry.MutexOnuImageStatus.Lock()
1605 pDevEntry.POnuImageStatus = nil
1606 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001607 return images, err
1608}
1609
Himani Chawla6d2ae152020-09-02 13:11:20 +05301610// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001611// #####################################################################################
1612
1613// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301614// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001615
dbainbri4d3a0dc2020-12-02 00:33:42 +00001616func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001617 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1618 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001619}
1620
1621// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001622func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001623
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001624 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001625 var err error
1626
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001627 // populate what we know. rest comes later after mib sync
1628 dh.device.Root = false
1629 dh.device.Vendor = "OpenONU"
1630 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001631 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001632 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001633
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001634 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001635
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001636 if !dh.IsReconciling() {
1637 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001638 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1639 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1640 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301641 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001642 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001643 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001644 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001645 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001646
Himani Chawla4d908332020-08-31 12:30:20 +05301647 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001648 dh.ponPortNumber = dh.device.ParentPortNo
1649
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001650 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1651 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1652 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001653 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001654 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301655 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001656
1657 /*
1658 self._pon = PonPort.create(self, self._pon_port_number)
1659 self._pon.add_peer(self.parent_id, self._pon_port_number)
1660 self.logger.debug('adding-pon-port-to-agent',
1661 type=self._pon.get_port().type,
1662 admin_state=self._pon.get_port().admin_state,
1663 oper_status=self._pon.get_port().oper_status,
1664 )
1665 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001666 if !dh.IsReconciling() {
1667 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001668 var ponPortNo uint32 = 1
1669 if dh.ponPortNumber != 0 {
1670 ponPortNo = dh.ponPortNumber
1671 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001672
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001673 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001674 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001675 PortNo: ponPortNo,
1676 Label: fmt.Sprintf("pon-%d", ponPortNo),
1677 Type: voltha.Port_PON_ONU,
1678 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301679 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001680 PortNo: ponPortNo}}, // Peer port is parent's port number
1681 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001682 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001683 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001684 e.Cancel(err)
1685 return
1686 }
1687 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001688 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001689 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001690 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001691}
1692
1693// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001694func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001695
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001696 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001697 var err error
1698 /*
1699 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1700 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1701 return nil
1702 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001703 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001704 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001705 e.Cancel(err)
1706 return
1707 }
1708
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001709 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001710 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001711 // reconcilement will be continued after mib download is done
1712 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001713
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001714 /*
1715 ############################################################################
1716 # Setup Alarm handler
1717 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1718 device.serial_number)
1719 ############################################################################
1720 # Setup PM configuration for this device
1721 # Pass in ONU specific options
1722 kwargs = {
1723 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1724 'heartbeat': self.heartbeat,
1725 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1726 }
1727 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1728 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1729 self.logical_device_id, device.serial_number,
1730 grouped=True, freq_override=False, **kwargs)
1731 pm_config = self._pm_metrics.make_proto()
1732 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1733 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1734 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1735
1736 # Note, ONU ID and UNI intf set in add_uni_port method
1737 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1738 ani_ports=[self._pon])
1739
1740 # Code to Run OMCI Test Action
1741 kwargs_omci_test_action = {
1742 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1743 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1744 }
1745 serial_number = device.serial_number
1746 self._test_request = OmciTestRequest(self.core_proxy,
1747 self.omci_agent, self.device_id,
1748 AniG, serial_number,
1749 self.logical_device_id,
1750 exclusive=False,
1751 **kwargs_omci_test_action)
1752
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001753 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001754 else:
1755 self.logger.info('onu-already-activated')
1756 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001757
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001758 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001759}
1760
1761// doStateConnected get the device info and update to voltha core
1762// for comparison of the original method (not that easy to uncomment): compare here:
1763// voltha-openolt-adapter/adaptercore/device_handler.go
1764// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001765func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001766
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001767 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301768 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001769 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001770 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001771}
1772
1773// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001774func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001775
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001776 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301777 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001778 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001779 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001780
1781 /*
1782 // Synchronous call to update device state - this method is run in its own go routine
1783 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1784 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001785 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 +00001786 return err
1787 }
1788 return nil
1789 */
1790}
1791
1792// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001793func (dh *deviceHandler) doStateDown(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, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001796 var err error
1797
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001798 device := dh.device
1799 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001800 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001801 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001802 e.Cancel(err)
1803 return
1804 }
1805
1806 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001807 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001808 /*
1809 // Update the all ports state on that device to disable
1810 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001811 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001812 return er
1813 }
1814
1815 //Update the device oper state and connection status
1816 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1817 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1818 dh.device = cloned
1819
1820 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001821 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001822 return er
1823 }
1824
1825 //get the child device for the parent device
1826 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1827 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001828 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001829 return err
1830 }
1831 for _, onuDevice := range onuDevices.Items {
1832
1833 // Update onu state as down in onu adapter
1834 onuInd := oop.OnuIndication{}
1835 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001836 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001837 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1838 if er != nil {
1839 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001840 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001841 //Do not return here and continue to process other ONUs
1842 }
1843 }
1844 // * Discovered ONUs entries need to be cleared , since after OLT
1845 // is up, it starts sending discovery indications again* /
1846 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001847 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001848 return nil
1849 */
Himani Chawla4d908332020-08-31 12:30:20 +05301850 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001851 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001852 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001853}
1854
Himani Chawla6d2ae152020-09-02 13:11:20 +05301855// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001856// #################################################################################
1857
1858// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301859// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001860
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001861//GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
1862func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001863 dh.lockDevice.RLock()
1864 pOnuDeviceEntry := dh.pOnuOmciDevice
1865 if aWait && pOnuDeviceEntry == nil {
1866 //keep the read sema short to allow for subsequent write
1867 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001868 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001869 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1870 // so it might be needed to wait here for that event with some timeout
1871 select {
1872 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001873 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001874 return nil
1875 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001876 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001877 // if written now, we can return the written value without sema
1878 return dh.pOnuOmciDevice
1879 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001880 }
mpagenko3af1f032020-06-10 08:53:41 +00001881 dh.lockDevice.RUnlock()
1882 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001883}
1884
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001885//setDeviceHandlerEntries sets the ONU device entry within the handler
1886func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1887 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001888 dh.lockDevice.Lock()
1889 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001890 dh.pOnuOmciDevice = apDeviceEntry
1891 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001892 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301893 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001894 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001895}
1896
Himani Chawla6d2ae152020-09-02 13:11:20 +05301897//addOnuDeviceEntry creates a new ONU device or returns the existing
1898func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001899 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001900
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001901 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001902 if deviceEntry == nil {
1903 /* costum_me_map in python code seems always to be None,
1904 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1905 /* also no 'clock' argument - usage open ...*/
1906 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001907 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1908 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1909 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1910 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1911 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001912 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001913 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001914 // fire deviceEntry ready event to spread to possibly waiting processing
1915 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001916 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001917 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001918 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001919 }
1920 // might be updated with some error handling !!!
1921 return nil
1922}
1923
dbainbri4d3a0dc2020-12-02 00:33:42 +00001924func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001925 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001926 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1927
1928 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001929
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001930 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001931 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001932 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1933 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001934 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001935 if !dh.IsReconciling() {
1936 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001937 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001938 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001939 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001940 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001941 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001942
khenaidoo42dcdfd2021-10-19 17:34:12 -04001943 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001944 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001945 OperStatus: voltha.OperStatus_ACTIVATING,
1946 ConnStatus: voltha.ConnectStatus_REACHABLE,
1947 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001948 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001949 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001950 }
1951 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001952 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001953 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001954
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001955 pDevEntry.MutexPersOnuConfig.RLock()
1956 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1957 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001958 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 +00001959 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001960 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001961 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001962 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001963 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001964 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001965 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1966 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1967 // 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 +00001968 // 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 +00001969 // so let's just try to keep it simple ...
1970 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001971 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001972 if err != nil || device == nil {
1973 //TODO: needs to handle error scenarios
1974 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1975 return errors.New("Voltha Device not found")
1976 }
1977 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001978
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001979 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001980 return err
mpagenko3af1f032020-06-10 08:53:41 +00001981 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001982 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001983
1984 /* this might be a good time for Omci Verify message? */
1985 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001986 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001987 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001988 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001989 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001990
1991 /* give the handler some time here to wait for the OMCi verification result
1992 after Timeout start and try MibUpload FSM anyway
1993 (to prevent stopping on just not supported OMCI verification from ONU) */
1994 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001995 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001996 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001997 case testresult := <-verifyExec:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001998 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001999 }
2000
2001 /* In py code it looks earlier (on activate ..)
2002 # Code to Run OMCI Test Action
2003 kwargs_omci_test_action = {
2004 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2005 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2006 }
2007 serial_number = device.serial_number
2008 self._test_request = OmciTestRequest(self.core_proxy,
2009 self.omci_agent, self.device_id,
2010 AniG, serial_number,
2011 self.logical_device_id,
2012 exclusive=False,
2013 **kwargs_omci_test_action)
2014 ...
2015 # Start test requests after a brief pause
2016 if not self._test_request_started:
2017 self._test_request_started = True
2018 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2019 reactor.callLater(tststart, self._test_request.start_collector)
2020
2021 */
2022 /* which is then: in omci_test_request.py : */
2023 /*
2024 def start_collector(self, callback=None):
2025 """
2026 Start the collection loop for an adapter if the frequency > 0
2027
2028 :param callback: (callable) Function to call to collect PM data
2029 """
2030 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2031 if callback is None:
2032 callback = self.perform_test_omci
2033
2034 if self.lc is None:
2035 self.lc = LoopingCall(callback)
2036
2037 if self.default_freq > 0:
2038 self.lc.start(interval=self.default_freq / 10)
2039
2040 def perform_test_omci(self):
2041 """
2042 Perform the initial test request
2043 """
2044 ani_g_entities = self._device.configuration.ani_g_entities
2045 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2046 is not None else None
2047 self._entity_id = ani_g_entities_ids[0]
2048 self.logger.info('perform-test', entity_class=self._entity_class,
2049 entity_id=self._entity_id)
2050 try:
2051 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2052 result = yield self._device.omci_cc.send(frame)
2053 if not result.fields['omci_message'].fields['success_code']:
2054 self.logger.info('Self-Test Submitted Successfully',
2055 code=result.fields[
2056 'omci_message'].fields['success_code'])
2057 else:
2058 raise TestFailure('Test Failure: {}'.format(
2059 result.fields['omci_message'].fields['success_code']))
2060 except TimeoutError as e:
2061 self.deferred.errback(failure.Failure(e))
2062
2063 except Exception as e:
2064 self.logger.exception('perform-test-Error', e=e,
2065 class_id=self._entity_class,
2066 entity_id=self._entity_id)
2067 self.deferred.errback(failure.Failure(e))
2068
2069 */
2070
2071 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002072 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002073
mpagenko1cc3cb42020-07-27 15:24:38 +00002074 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2075 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2076 * 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 +05302077 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002078 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002079 //call MibUploadFSM - transition up to state UlStInSync
2080 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002081 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002082 if pMibUlFsm.Is(mib.UlStDisabled) {
2083 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2084 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2085 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302086 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002087 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302088 //Determine ONU status and start/re-start MIB Synchronization tasks
2089 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002090 if pDevEntry.IsNewOnu() {
2091 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2092 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2093 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002094 }
Himani Chawla4d908332020-08-31 12:30:20 +05302095 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002096 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2097 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2098 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302099 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002100 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002101 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002102 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002103 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002104 "device-id": dh.DeviceID})
2105 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002106 }
2107 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002108 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2109 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002110 }
2111 return nil
2112}
2113
dbainbri4d3a0dc2020-12-02 00:33:42 +00002114func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00002115 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002116 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002117 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
2118 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002119
mpagenko900ee4b2020-10-12 11:56:34 +00002120 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2121 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2122 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002123 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002124 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002125 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002126 // abort: system behavior is just unstable ...
2127 return err
2128 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002129 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002130 _ = 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 +00002131
2132 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002133 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002134 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002135 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002136 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2137 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002138 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002139 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002140
2141 //TODO!!! remove existing traffic profiles
2142 /* from py code, if TP's exist, remove them - not yet implemented
2143 self._tp = dict()
2144 # Let TP download happen again
2145 for uni_id in self._tp_service_specific_task:
2146 self._tp_service_specific_task[uni_id].clear()
2147 for uni_id in self._tech_profile_download_done:
2148 self._tech_profile_download_done[uni_id].clear()
2149 */
2150
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002151 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002152
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002153 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002154
mpagenkoe4782082021-11-25 12:04:26 +00002155 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002156 // abort: system behavior is just unstable ...
2157 return err
2158 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002159 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002160 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002161 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002162 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002163 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2164 OperStatus: voltha.OperStatus_DISCOVERED,
2165 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002166 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002167 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002168 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002169 // abort: system behavior is just unstable ...
2170 return err
2171 }
2172 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002173 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002174 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002175 return nil
2176}
2177
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002178func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002179 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2180 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2181 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2182 // and using the stop/reset event should never harm
2183
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002184 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002185 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002186 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2187 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00002188 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002189 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002190 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002191 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002192 pDevEntry.MutexOnuImageStatus.RLock()
2193 if pDevEntry.POnuImageStatus != nil {
2194 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002195 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002196 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002197
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002198 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002199 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002200 }
2201 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002202 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002203 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002204 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002205 }
mpagenko101ac942021-11-16 15:01:29 +00002206 //stop any deviceHandler reconcile processing (if running)
2207 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002208 //port lock/unlock FSM's may be active
2209 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002210 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002211 }
2212 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002213 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002214 }
2215 //techProfile related PonAniConfigFsm FSM may be active
2216 if dh.pOnuTP != nil {
2217 // should always be the case here
2218 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002219 if dh.pOnuTP.PAniConfigFsm != nil {
2220 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2221 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002222 }
mpagenko900ee4b2020-10-12 11:56:34 +00002223 }
2224 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002225 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002226 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002227 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002228 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002229 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002230 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002231 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002232 } else {
2233 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002234 }
2235 }
2236 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002237 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002238 // Stop collector routine
2239 dh.stopCollector <- true
2240 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002241 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302242 dh.stopAlarmManager <- true
2243 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002244 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002245 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002246 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302247
Girish Gowdrae95687a2021-09-08 16:30:58 -07002248 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2249
mpagenko80622a52021-02-09 16:53:23 +00002250 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002251 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002252 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002253 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002254 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002255 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002256 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002257 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2258 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2259 // (even though it may also run into direct cancellation, a bit hard to verify here)
2260 // so don't set 'dh.upgradeCanceled = true' here!
2261 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2262 }
mpagenko38662d02021-08-11 09:45:19 +00002263 }
mpagenko80622a52021-02-09 16:53:23 +00002264
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002265 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002266 return nil
2267}
2268
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002269func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2270 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 +05302271
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002272 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002273 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002274 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002275 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002276 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002277 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002278 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002279
mpagenkoa40e99a2020-11-17 13:50:39 +00002280 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2281 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2282 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2283 * disable/enable toggling here to allow traffic
2284 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2285 * like the py comment says:
2286 * # start by locking all the unis till mib sync and initial mib is downloaded
2287 * # this way we can capture the port down/up events when we are ready
2288 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302289
mpagenkoa40e99a2020-11-17 13:50:39 +00002290 // Init Uni Ports to Admin locked state
2291 // *** should generate UniLockStateDone event *****
2292 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002293 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002294 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002295 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002296 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002297 }
2298}
2299
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002300func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2301 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302302 /* Mib download procedure -
2303 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2304 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002305 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002306 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002307 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002308 return
2309 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002310 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302311 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002312 if pMibDlFsm.Is(mib.DlStDisabled) {
2313 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2314 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 +05302315 // maybe try a FSM reset and then again ... - TODO!!!
2316 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002317 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302318 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002319 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2320 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302321 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002322 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302323 //Begin MIB data download (running autonomously)
2324 }
2325 }
2326 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002327 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002328 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302329 // maybe try a FSM reset and then again ... - TODO!!!
2330 }
2331 /***** Mib download started */
2332 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002333 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302334 }
2335}
2336
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002337func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2338 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302339 //initiate DevStateUpdate
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002340 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002341 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002342 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002343 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2344 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2345 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2346 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002347 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002348 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002349 ConnStatus: voltha.ConnectStatus_REACHABLE,
2350 OperStatus: voltha.OperStatus_ACTIVE,
2351 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302352 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002353 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302354 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002355 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302356 }
2357 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002358 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002359 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302360 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002361 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002362
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002363 if !dh.GetCollectorIsRunning() {
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002364 // Start PM collector routine
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002365 go dh.StartCollector(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002366 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002367 if !dh.GetAlarmManagerIsRunning(ctx) {
2368 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002369 }
2370
Girish Gowdrae95687a2021-09-08 16:30:58 -07002371 // Start flow handler routines per UNI
2372 for _, uniPort := range dh.uniEntityMap {
2373 // only if this port was enabled for use by the operator at startup
2374 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2375 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2376 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2377 }
2378 }
2379 }
2380
Girish Gowdrae0140f02021-02-02 16:55:09 -08002381 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002382 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002383 // There is no way we should be landing here, but if we do then
2384 // there is nothing much we can do about this other than log error
2385 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2386 }
2387
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002388 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002389
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002390 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002391 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002392 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002393 return
2394 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002395 pDevEntry.MutexPersOnuConfig.RLock()
2396 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2397 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002398 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002399 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002400 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002401 // reconcilement will be continued after ani config is done
2402 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002403 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002404 // *** should generate UniUnlockStateDone event *****
2405 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002406 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002407 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002408 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002409 dh.runUniLockFsm(ctx, false)
2410 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302411 }
2412}
2413
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002414func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2415 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302416
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002417 if !dh.IsReconciling() {
2418 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002419 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002420 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2421 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002422 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002423 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002424 return
2425 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002426 pDevEntry.MutexPersOnuConfig.Lock()
2427 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2428 pDevEntry.MutexPersOnuConfig.Unlock()
2429 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002430 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002431 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002432 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302433 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002434 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 +00002435 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002436 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002437 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302438 }
2439}
2440
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002441func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002442 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002443 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002444
mpagenko44bd8362021-11-15 11:40:05 +00002445 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002446 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002447 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002448 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002449 OperStatus: voltha.OperStatus_UNKNOWN,
2450 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002451 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002452 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002453 }
2454
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002455 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002456 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002457 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002458
2459 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002460 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002461
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002462 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002463 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002464 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002465 return
2466 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002467 pDevEntry.MutexPersOnuConfig.Lock()
2468 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2469 pDevEntry.MutexPersOnuConfig.Unlock()
2470 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002471 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002472 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002473 }
mpagenko900ee4b2020-10-12 11:56:34 +00002474}
2475
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002476func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002477 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002478 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002479 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002480 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002481 ConnStatus: voltha.ConnectStatus_REACHABLE,
2482 OperStatus: voltha.OperStatus_ACTIVE,
2483 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002484 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002485 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002486 }
2487
dbainbri4d3a0dc2020-12-02 00:33:42 +00002488 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002489 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002490 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002491 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002492
2493 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002494 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002495
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002496 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002497 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002498 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002499 return
2500 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002501 pDevEntry.MutexPersOnuConfig.Lock()
2502 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2503 pDevEntry.MutexPersOnuConfig.Unlock()
2504 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002505 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002506 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002507 }
mpagenko900ee4b2020-10-12 11:56:34 +00002508}
2509
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002510func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2511 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2512 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002513 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002514 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002515 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002516 OperStatus: voltha.OperStatus_FAILED,
2517 }); err != nil {
2518 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2519 }
2520}
2521
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002522func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2523 if devEvent == cmn.OmciAniConfigDone {
2524 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002525 // attention: the device reason update is done based on ONU-UNI-Port related activity
2526 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002527 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002528 // 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 +00002529 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302530 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002531 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002532 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
2533 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
2534 dh.mutexReconcilingFirstPassFlag.Lock()
2535 if dh.reconcilingFirstPass {
2536 logger.Debugw(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
2537 dh.reconcilingFirstPass = false
2538 go dh.ReconcileDeviceFlowConfig(ctx)
2539 }
2540 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00002541 }
2542 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002543 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002544 // attention: the device reason update is done based on ONU-UNI-Port related activity
2545 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002546 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002547 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
2548 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002549 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002550 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302551}
2552
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002553func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002554 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002555 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302556 // attention: the device reason update is done based on ONU-UNI-Port related activity
2557 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302558
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002559 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2560 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00002561 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00002562 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002563 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00002564 }
2565 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002566 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002567 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00002568 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002569 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302570 }
mpagenkof1fc3862021-02-16 10:09:52 +00002571
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002572 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002573 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002574 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002575 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002576 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002577 }
2578 } else {
2579 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002580 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002581 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302582}
2583
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002584//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
2585func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302586 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002587 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002588 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002589 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002590 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002591 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002592 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002593 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002594 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002595 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002596 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002597 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002598 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002599 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002600 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002601 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002602 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002603 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002604 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002605 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002606 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002607 case cmn.UniEnableStateFailed:
2608 {
2609 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2610 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002611 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002612 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002613 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002614 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002615 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002616 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002617 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002618 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002619 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002620 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002621 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002622 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002623 default:
2624 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002625 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002626 }
2627 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002628}
2629
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002630func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002631 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002632 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302633 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002634 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002635 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002636 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302637 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002638 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002639 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002640 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 +00002641 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002642 //store UniPort with the System-PortNumber key
2643 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002644 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002645 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002646 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002647 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002648 } //error logging already within UniPort method
2649 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002650 logger.Debugw(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002651 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002652 }
2653 }
2654}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002655
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002656func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2657 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002658 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002659 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002660 return
2661 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002662 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002663 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002664 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2665 for _, mgmtEntityID := range pptpInstKeys {
2666 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002667 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002668 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2669 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002670 }
2671 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002672 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002673 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002674 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002675 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2676 for _, mgmtEntityID := range veipInstKeys {
2677 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002678 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002679 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2680 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002681 }
2682 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002683 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002684 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002685 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002686 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2687 for _, mgmtEntityID := range potsInstKeys {
2688 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002689 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002690 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2691 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002692 }
2693 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002694 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002695 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002696 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002697 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002698 return
2699 }
2700
mpagenko2c3f6c52021-11-23 11:22:10 +00002701 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
2702 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
2703 // 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 -07002704 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2705 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2706 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00002707 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
2708 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002709 for i := 0; i < int(uniCnt); i++ {
2710 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
2711 dh.stopFlowMonitoringRoutine[i] = make(chan bool)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002712 }
2713}
2714
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002715// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2716func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002717 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302718 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002719 // with following remark:
2720 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2721 // # load on the core
2722
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002723 // 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 +00002724
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002725 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002726 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002727 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2728 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2729 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2730 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002731 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002732 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002733 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002734 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002735 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002736 PortNo: port.PortNo,
2737 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002738 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002739 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 -04002740 }
2741 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002742 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002743 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002744 }
mpagenko3af1f032020-06-10 08:53:41 +00002745 }
2746 }
2747}
2748
2749// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002750func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2751 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002752 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2753 for uniNo, uniPort := range dh.uniEntityMap {
2754 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002755
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-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2758 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2759 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +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 Hildebrandtbe523842021-03-10 10:47:18 +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 Hildebrandtbe523842021-03-10 10:47:18 +00002773 }
2774
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002775 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002776 }
2777}
2778
2779// ONU_Active/Inactive announcement on system KAFKA bus
2780// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002781func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002782 var de voltha.DeviceEvent
2783 eventContext := make(map[string]string)
2784 //Populating event context
2785 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002786 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002787 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002788 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002789 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002790 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 +00002791 }
2792 oltSerialNumber := parentDevice.SerialNumber
2793
2794 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2795 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2796 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302797 eventContext["olt-serial-number"] = oltSerialNumber
2798 eventContext["device-id"] = aDeviceID
2799 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002800 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002801 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2802 deviceEntry.MutexPersOnuConfig.RLock()
2803 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2804 deviceEntry.MutexPersOnuConfig.RUnlock()
2805 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
2806 deviceEntry.MutexPersOnuConfig.RLock()
2807 eventContext["vendor"] = deviceEntry.SOnuPersistentData.PersVendorID
2808 deviceEntry.MutexPersOnuConfig.RUnlock()
2809 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002810 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2811 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2812 } else {
2813 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2814 log.Fields{"device-id": aDeviceID})
2815 return
2816 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002817
2818 /* Populating device event body */
2819 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302820 de.ResourceId = aDeviceID
2821 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002822 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2823 de.Description = fmt.Sprintf("%s Event - %s - %s",
2824 cEventObjectType, cOnuActivatedEvent, "Raised")
2825 } else {
2826 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2827 de.Description = fmt.Sprintf("%s Event - %s - %s",
2828 cEventObjectType, cOnuActivatedEvent, "Cleared")
2829 }
2830 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002831 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2832 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302833 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002834 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002835 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302836 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002837}
2838
Himani Chawla4d908332020-08-31 12:30:20 +05302839// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002840func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2841 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002842 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302843 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002844 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002845 sFsmName = "LockStateFSM"
2846 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002847 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002848 sFsmName = "UnLockStateFSM"
2849 }
mpagenko3af1f032020-06-10 08:53:41 +00002850
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002851 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002852 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002853 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002854 return
2855 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002856 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002857 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302858 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002859 dh.pLockStateFsm = pLSFsm
2860 } else {
2861 dh.pUnlockStateFsm = pLSFsm
2862 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002863 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002864 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002865 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002866 }
2867}
2868
2869// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002870func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002871 /* Uni Port lock/unlock procedure -
2872 ***** should run via 'adminDone' state and generate the argument requested event *****
2873 */
2874 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302875 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002876 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002877 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2878 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002879 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2880 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002881 }
2882 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002883 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002884 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2885 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002886 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2887 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002888 }
2889 }
2890 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002891 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2892 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002893 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002894 // maybe try a FSM reset and then again ... - TODO!!!
2895 } else {
2896 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002897 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002898 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002899 }
2900 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002901 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002902 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002903 // maybe try a FSM reset and then again ... - TODO!!!
2904 }
2905 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002906 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002907 // maybe try a FSM reset and then again ... - TODO!!!
2908 }
2909}
2910
mpagenko80622a52021-02-09 16:53:23 +00002911// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00002912// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002913func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002914 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002915 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002916 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002917 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002918 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002919 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002920 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002921 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002922 sFsmName, chUpgradeFsm)
2923 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002924 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00002925 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002926 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
2927 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002928 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00002929 // maybe try a FSM reset and then again ... - TODO!!!
2930 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2931 }
mpagenko59862f02021-10-11 08:53:18 +00002932 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00002933 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2934 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00002935 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2936 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002937 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002938 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002939 } else {
2940 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002941 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002942 // maybe try a FSM reset and then again ... - TODO!!!
2943 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2944 }
2945 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002946 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002947 // maybe try a FSM reset and then again ... - TODO!!!
2948 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2949 }
2950 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002951 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002952 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2953 }
2954 return nil
2955}
2956
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002957// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
2958func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002959 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002960 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002961 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00002962 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2963 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00002964 dh.pLastUpgradeImageState = apImageState
2965 dh.lockUpgradeFsm.Unlock()
2966 //signal upgradeFsm removed using non-blocking channel send
2967 select {
2968 case dh.upgradeFsmChan <- struct{}{}:
2969 default:
2970 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002971 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00002972 }
mpagenko80622a52021-02-09 16:53:23 +00002973}
2974
mpagenko15ff4a52021-03-02 10:09:20 +00002975// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2976func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002977 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00002978 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002979 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002980 return
2981 }
2982
2983 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00002984 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00002985 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002986 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
2987 dh.lockUpgradeFsm.RUnlock()
2988 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
2989 return
2990 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002991 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00002992 if pUpgradeStatemachine != nil {
2993 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2994 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002995 UpgradeState := pUpgradeStatemachine.Current()
2996 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
2997 (UpgradeState == swupg.UpgradeStRequestingActivate) {
2998 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00002999 // 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 +00003000 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003001 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3002 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003003 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003004 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003005 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003006 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3007 dh.upgradeCanceled = true
3008 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3009 }
mpagenko15ff4a52021-03-02 10:09:20 +00003010 return
3011 }
mpagenko59862f02021-10-11 08:53:18 +00003012 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003013 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3014 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003015 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003016 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003017 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3018 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003019 return
3020 }
3021 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003022 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003023 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003024 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3025 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003026 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3027 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003028 return
3029 }
3030 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003031 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003032 }
3033 } else {
3034 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 +00003035 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003036 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3037 dh.upgradeCanceled = true
3038 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3039 }
mpagenko1f8e8822021-06-25 14:10:21 +00003040 }
mpagenko15ff4a52021-03-02 10:09:20 +00003041 return
3042 }
mpagenko59862f02021-10-11 08:53:18 +00003043 dh.lockUpgradeFsm.RUnlock()
3044 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3045 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003046 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3047 dh.upgradeCanceled = true
3048 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3049 }
mpagenko59862f02021-10-11 08:53:18 +00003050 return
3051 }
3052 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3053 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3054 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3055 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3056 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3057 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3058 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003059 }
mpagenko15ff4a52021-03-02 10:09:20 +00003060 }
3061 }
3062 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003063 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003064 }
mpagenko59862f02021-10-11 08:53:18 +00003065 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003066}
3067
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003068//SetBackend provides a DB backend for the specified path on the existing KV client
3069func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003070
3071 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003072 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003073 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003074 kvbackend := &db.Backend{
3075 Client: dh.pOpenOnuAc.kvClient,
3076 StoreType: dh.pOpenOnuAc.KVStoreType,
3077 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003078 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003079 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3080 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003081
mpagenkoaf801632020-07-03 10:00:42 +00003082 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003083}
khenaidoo7d3c5582021-08-11 18:09:44 -04003084func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05303085 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003086
mpagenkodff5dda2020-08-28 11:52:01 +00003087 for _, field := range flow.GetOfbFields(apFlowItem) {
3088 switch field.Type {
3089 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3090 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003091 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003092 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3093 }
mpagenko01e726e2020-10-23 09:45:29 +00003094 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003095 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3096 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303097 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003098 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303099 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3100 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003101 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3102 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003103 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003104 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303105 return
mpagenkodff5dda2020-08-28 11:52:01 +00003106 }
3107 }
mpagenko01e726e2020-10-23 09:45:29 +00003108 */
mpagenkodff5dda2020-08-28 11:52:01 +00003109 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3110 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303111 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003112 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303113 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003114 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303115 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003116 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003117 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303118 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003119 }
3120 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3121 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303122 *loAddPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003123 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003124 "PCP": loAddPcp})
3125 }
3126 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3127 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003128 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003129 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3130 }
3131 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3132 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003133 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003134 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3135 }
3136 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3137 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003138 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003139 "IPv4-DST": field.GetIpv4Dst()})
3140 }
3141 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3142 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003143 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003144 "IPv4-SRC": field.GetIpv4Src()})
3145 }
3146 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3147 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003148 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003149 "Metadata": field.GetTableMetadata()})
3150 }
3151 /*
3152 default:
3153 {
3154 //all other entires ignored
3155 }
3156 */
3157 }
3158 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303159}
mpagenkodff5dda2020-08-28 11:52:01 +00003160
khenaidoo7d3c5582021-08-11 18:09:44 -04003161func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003162 for _, action := range flow.GetActions(apFlowItem) {
3163 switch action.Type {
3164 /* not used:
3165 case of.OfpActionType_OFPAT_OUTPUT:
3166 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003167 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003168 "Output": action.GetOutput()})
3169 }
3170 */
3171 case of.OfpActionType_OFPAT_PUSH_VLAN:
3172 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003173 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003174 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3175 }
3176 case of.OfpActionType_OFPAT_SET_FIELD:
3177 {
3178 pActionSetField := action.GetSetField()
3179 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003180 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003181 "OxcmClass": pActionSetField.Field.OxmClass})
3182 }
3183 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303184 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003185 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303186 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003187 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303188 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003189 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303190 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003191 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003192 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003193 "Type": pActionSetField.Field.GetOfbField().Type})
3194 }
3195 }
3196 /*
3197 default:
3198 {
3199 //all other entires ignored
3200 }
3201 */
3202 }
3203 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303204}
3205
3206//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003207func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003208 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303209 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3210 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
3211 var loAddPcp, loSetPcp uint8
3212 var loIPProto uint32
3213 /* the TechProfileId is part of the flow Metadata - compare also comment within
3214 * OLT-Adapter:openolt_flowmgr.go
3215 * Metadata 8 bytes:
3216 * Most Significant 2 Bytes = Inner VLAN
3217 * Next 2 Bytes = Tech Profile ID(TPID)
3218 * Least Significant 4 Bytes = Port ID
3219 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3220 * subscriber related flows.
3221 */
3222
dbainbri4d3a0dc2020-12-02 00:33:42 +00003223 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303224 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003225 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003226 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003227 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303228 }
mpagenko551a4d42020-12-08 18:09:20 +00003229 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003230 loCookie := apFlowItem.GetCookie()
3231 loCookieSlice := []uint64{loCookie}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003232 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003233 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05303234
dbainbri4d3a0dc2020-12-02 00:33:42 +00003235 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003236 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303237 if loIPProto == 2 {
3238 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3239 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003240 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003241 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303242 return nil
3243 }
mpagenko01e726e2020-10-23 09:45:29 +00003244 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003245 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003246
3247 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003248 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003249 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003250 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3251 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3252 //TODO!!: Use DeviceId within the error response to rwCore
3253 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003254 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003255 }
3256 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003257 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003258 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3259 } else {
3260 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3261 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3262 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303263 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003264 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003265 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003266 }
mpagenko9a304ea2020-12-16 15:54:01 +00003267
khenaidoo42dcdfd2021-10-19 17:34:12 -04003268 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003269 if apFlowMetaData != nil {
3270 meter = apFlowMetaData.Meters[0]
3271 }
mpagenkobc4170a2021-08-17 16:42:10 +00003272 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3273 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3274 // when different rules are requested concurrently for the same uni
3275 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3276 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3277 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003278 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3279 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003280 //SetUniFlowParams() may block on some rule that is suspended-to-add
3281 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003282 // Also the error is returned to caller via response channel
3283 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
3284 loMatchVlan, loSetVlan, loSetPcp, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003285 dh.lockVlanConfig.RUnlock()
3286 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003287 return
mpagenkodff5dda2020-08-28 11:52:01 +00003288 }
mpagenkobc4170a2021-08-17 16:42:10 +00003289 dh.lockVlanConfig.RUnlock()
3290 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003291 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003292 loMatchVlan, loSetVlan, loSetPcp, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003293 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003294 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003295 if err != nil {
3296 *respChan <- err
3297 }
mpagenko01e726e2020-10-23 09:45:29 +00003298}
3299
3300//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003301func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003302 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3303 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3304 //no extra check is done on the rule parameters
3305 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3306 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3307 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3308 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003309 // - 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 +00003310 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003311 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003312
3313 /* TT related temporary workaround - should not be needed anymore
3314 for _, field := range flow.GetOfbFields(apFlowItem) {
3315 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3316 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003317 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003318 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3319 if loIPProto == 2 {
3320 // 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 +00003321 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003322 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003323 return nil
3324 }
3325 }
3326 } //for all OfbFields
3327 */
3328
mpagenko9a304ea2020-12-16 15:54:01 +00003329 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003330 dh.lockVlanConfig.RLock()
3331 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003332 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3333 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003334 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3335 return
mpagenko01e726e2020-10-23 09:45:29 +00003336 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003337 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003338 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003339 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003340 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003341 // Push response on the response channel
3342 if respChan != nil {
3343 // 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
3344 select {
3345 case *respChan <- nil:
3346 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3347 default:
3348 }
3349 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003350 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003351}
3352
Himani Chawla26e555c2020-08-31 12:30:20 +05303353// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003354// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003355// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003356func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003357 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 +00003358 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003359
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003360 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003361 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003362 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3363 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003364 }
3365
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003366 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3367 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003368 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003369 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003370 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3371 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003372 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3373 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003374 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003375 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3376 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003377 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3378 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003379 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003380 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303381 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003382 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003383 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3384 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003385 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003386 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003387 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3388 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003389 }
3390 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003391 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003392 "device-id": dh.DeviceID})
3393 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003394 }
3395 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003396 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003397 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3398 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003399 }
3400 return nil
3401}
3402
mpagenkofc4f56e2020-11-04 17:17:49 +00003403//VerifyVlanConfigRequest checks on existence of a given uniPort
3404// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003405func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003406 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003407 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003408 for _, uniPort := range dh.uniEntityMap {
3409 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003410 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003411 pCurrentUniPort = uniPort
3412 break //found - end search loop
3413 }
3414 }
3415 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003416 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003417 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003418 return
3419 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003420 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003421}
3422
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003423//VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
3424func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003425 //TODO!! verify and start pending flow configuration
3426 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3427 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003428
3429 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003430 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003431 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003432 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003433 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003434 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003435 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003436 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003437 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3438 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003439 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003440 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003441 } else {
3442 /***** UniVlanConfigFsm continued */
3443 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003444 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3445 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003446 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003447 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3448 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003449 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003450 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003451 } else {
3452 /***** UniVlanConfigFsm continued */
3453 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003454 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3455 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003456 }
mpagenkodff5dda2020-08-28 11:52:01 +00003457 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003458 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003459 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3460 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003461 }
3462 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003463 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 +00003464 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3465 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003466 }
3467 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003468 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003469 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003470 }
mpagenkof1fc3862021-02-16 10:09:52 +00003471 } else {
3472 dh.lockVlanConfig.RUnlock()
3473 }
mpagenkodff5dda2020-08-28 11:52:01 +00003474}
3475
3476//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3477// 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 +00003478func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003479 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003480 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003481 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003482 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003483 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003484 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003485}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003486
mpagenkof1fc3862021-02-16 10:09:52 +00003487//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003488func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003489 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3490 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3491 // obviously then parallel processing on the cancel must be avoided
3492 // deadline context to ensure completion of background routines waited for
3493 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3494 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3495 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3496
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003497 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003498 var wg sync.WaitGroup
3499 wg.Add(1) // for the 1 go routine to finish
3500
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003501 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003502 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3503
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003504 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003505}
3506
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003507//StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003508//available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003509func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3510 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003511
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003512 if dh.IsReconciling() {
3513 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003514 return nil
3515 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003516 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003517
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003518 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003519 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003520 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3521 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003522 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003523 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003524
mpagenkof1fc3862021-02-16 10:09:52 +00003525 if aWriteToKvStore {
3526 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3527 }
3528 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003529}
3530
dbainbri4d3a0dc2020-12-02 00:33:42 +00003531func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003532 defer cancel() //ensure termination of context (may be pro forma)
3533 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003534 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003535 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003536}
3537
mpagenkoe4782082021-11-25 12:04:26 +00003538//ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
3539// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
3540func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
3541 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
3542 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
3543 dh.mutexDeviceReason.Lock()
3544 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003545 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003546 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003547 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003548 DeviceId: dh.DeviceID,
3549 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003550 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00003551 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003552 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003553 return err
3554 }
mpagenkoe4782082021-11-25 12:04:26 +00003555 } else {
3556 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 +00003557 }
mpagenkoe4782082021-11-25 12:04:26 +00003558 dh.deviceReason = deviceReason
3559 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
3560 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003561 return nil
3562}
3563
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003564func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3565 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003566 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003567 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3568 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003569 }
mpagenkof1fc3862021-02-16 10:09:52 +00003570 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003571}
3572
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003573// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003574// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003575func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3576 dh.lockDevice.RLock()
3577 defer dh.lockDevice.RUnlock()
3578 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003579 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003580 }
3581 return 0, errors.New("error-fetching-uni-port")
3582}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003583
3584// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003585func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3586 var errorsList []error
3587 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 -08003588
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003589 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3590 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3591 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3592
3593 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3594 // successfully.
3595 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3596 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3597 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003598 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 -08003599 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003600 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003601 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003602 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003603}
3604
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003605func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3606 var err error
3607 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003608 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003609
3610 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003611 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003612 errorsList = append(errorsList, err)
3613 }
3614 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003615 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003616
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003617 return errorsList
3618}
3619
3620func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3621 var err error
3622 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003623 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003624 // Check if group metric related config is updated
3625 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003626 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3627 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3628 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003629
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003630 if ok && m.Frequency != v.GroupFreq {
3631 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003632 errorsList = append(errorsList, err)
3633 }
3634 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003635 if ok && m.Enabled != v.Enabled {
3636 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003637 errorsList = append(errorsList, err)
3638 }
3639 }
3640 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003641 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003642 return errorsList
3643}
3644
3645func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3646 var err error
3647 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003648 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003649 // Check if standalone metric related config is updated
3650 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003651 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3652 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3653 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003654
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003655 if ok && m.Frequency != v.SampleFreq {
3656 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003657 errorsList = append(errorsList, err)
3658 }
3659 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003660 if ok && m.Enabled != v.Enabled {
3661 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003662 errorsList = append(errorsList, err)
3663 }
3664 }
3665 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003666 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003667 return errorsList
3668}
3669
3670// nolint: gocyclo
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003671func (dh *deviceHandler) StartCollector(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003672 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08003673
3674 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003675 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303676 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003677 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003678 // Initialize the next metric collection time.
3679 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3680 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003681 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003682 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003683 for {
3684 select {
3685 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003686 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003687 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003688 // Stop the L2 PM FSM
3689 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003690 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3691 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3692 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003693 }
3694 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003695 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003696 }
3697 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003698 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3699 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003700 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003701 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3702 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003703 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003704
Girish Gowdrae09a6202021-01-12 18:10:59 -08003705 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003706 case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3707 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3708 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3709 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3710 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003711 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003712 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003713 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003714 } else {
3715 if dh.pmConfigs.Grouped { // metrics are managed as a group
3716 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003717 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003718
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003719 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3720 // 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 -08003721 // 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 +00003722 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3723 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003724 }
3725 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003726 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3727 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3728 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3729 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003730 }
3731 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003732 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003733
3734 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003735 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3736 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3737 // 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 -08003738 // 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 +00003739 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3740 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003741 }
3742 }
3743 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003744 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3745 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3746 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3747 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003748 }
3749 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003750 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003751 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003752 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003753 } */
3754 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003755 }
3756 }
3757}
kesavandfdf77632021-01-26 23:40:33 -05003758
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003759func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003760
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003761 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3762 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003763}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003764
Himani Chawla43f95ff2021-06-03 00:24:12 +05303765func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3766 if dh.pOnuMetricsMgr == nil {
3767 return &extension.SingleGetValueResponse{
3768 Response: &extension.GetValueResponse{
3769 Status: extension.GetValueResponse_ERROR,
3770 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3771 },
3772 }
3773 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303774 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303775 return resp
3776}
3777
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003778func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3779 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003780 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003781 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003782 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003783}
3784
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003785func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003786 var pAdapterFsm *cmn.AdapterFsm
3787 //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 +00003788 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003789 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003790 {
mpagenkofbf577d2021-10-12 11:44:33 +00003791 if dh.pOnuOmciDevice != nil {
3792 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3793 } else {
3794 return true //FSM not active - so there is no activity on omci
3795 }
mpagenkof1fc3862021-02-16 10:09:52 +00003796 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003797 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003798 {
mpagenkofbf577d2021-10-12 11:44:33 +00003799 if dh.pOnuOmciDevice != nil {
3800 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3801 } else {
3802 return true //FSM not active - so there is no activity on omci
3803 }
mpagenkof1fc3862021-02-16 10:09:52 +00003804 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003805 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003806 {
mpagenkofbf577d2021-10-12 11:44:33 +00003807 if dh.pLockStateFsm != nil {
3808 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3809 } else {
3810 return true //FSM not active - so there is no activity on omci
3811 }
mpagenkof1fc3862021-02-16 10:09:52 +00003812 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003813 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003814 {
mpagenkofbf577d2021-10-12 11:44:33 +00003815 if dh.pUnlockStateFsm != nil {
3816 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3817 } else {
3818 return true //FSM not active - so there is no activity on omci
3819 }
mpagenkof1fc3862021-02-16 10:09:52 +00003820 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003821 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003822 {
mpagenkofbf577d2021-10-12 11:44:33 +00003823 if dh.pOnuMetricsMgr != nil {
3824 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003825 } else {
3826 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003827 }
3828 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003829 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003830 {
3831 dh.lockUpgradeFsm.RLock()
3832 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003833 if dh.pOnuUpradeFsm != nil {
3834 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3835 } else {
3836 return true //FSM not active - so there is no activity on omci
3837 }
mpagenko80622a52021-02-09 16:53:23 +00003838 }
mpagenkof1fc3862021-02-16 10:09:52 +00003839 default:
3840 {
3841 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003842 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003843 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003844 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003845 }
mpagenkofbf577d2021-10-12 11:44:33 +00003846 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3847 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3848 }
3849 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003850}
3851
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003852func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3853 for _, v := range dh.pOnuTP.PAniConfigFsm {
3854 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003855 return false
3856 }
3857 }
3858 return true
3859}
3860
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003861func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003862 dh.lockVlanConfig.RLock()
3863 defer dh.lockVlanConfig.RUnlock()
3864 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003865 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003866 return false
3867 }
3868 }
3869 return true //FSM not active - so there is no activity on omci
3870}
3871
3872func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3873 dh.lockVlanConfig.RLock()
3874 defer dh.lockVlanConfig.RUnlock()
3875 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003876 if v.PAdaptFsm.PFsm != nil {
3877 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003878 return true //there is at least one VLAN FSM with some active configuration
3879 }
3880 }
3881 }
3882 return false //there is no VLAN FSM with some active configuration
3883}
3884
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003885func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003886 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3887 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3888 return false
3889 }
3890 }
3891 // a further check is done to identify, if at least some data traffic related configuration exists
3892 // 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])
3893 return dh.checkUserServiceExists(ctx)
3894}
3895
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003896func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003897 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3898 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003899 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003900 // TODO: fatal error reset ONU, delete deviceHandler!
3901 return
3902 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003903 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
3904 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003905}
3906
3907func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3908 dh.mutexCollectorFlag.Lock()
3909 dh.collectorIsRunning = flagValue
3910 dh.mutexCollectorFlag.Unlock()
3911}
3912
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003913func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003914 dh.mutexCollectorFlag.RLock()
3915 flagValue := dh.collectorIsRunning
3916 dh.mutexCollectorFlag.RUnlock()
3917 return flagValue
3918}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303919
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303920func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3921 dh.mutextAlarmManagerFlag.Lock()
3922 dh.alarmManagerIsRunning = flagValue
3923 dh.mutextAlarmManagerFlag.Unlock()
3924}
3925
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003926func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303927 dh.mutextAlarmManagerFlag.RLock()
3928 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003929 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303930 dh.mutextAlarmManagerFlag.RUnlock()
3931 return flagValue
3932}
3933
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003934func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003935 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303936
3937 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003938 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303939 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303940 if stop := <-dh.stopAlarmManager; stop {
3941 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303942 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303943 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003944 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
3945 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05303946 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303947 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003948 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
3949 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05303950 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303951 }
3952}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003953
Girish Gowdrae95687a2021-09-08 16:30:58 -07003954func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
3955 dh.mutexFlowMonitoringRoutineFlag.Lock()
3956 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003957 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003958 dh.isFlowMonitoringRoutineActive[uniID] = flag
3959}
3960
3961func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
3962 dh.mutexFlowMonitoringRoutineFlag.RLock()
3963 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
3964 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003965 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003966 return dh.isFlowMonitoringRoutineActive[uniID]
3967}
3968
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003969func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
3970 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003971
Maninder7961d722021-06-16 22:10:28 +05303972 connectStatus := voltha.ConnectStatus_UNREACHABLE
3973 operState := voltha.OperStatus_UNKNOWN
3974
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003975 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003976 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003977 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00003978 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003979 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003980 case success := <-dh.chReconcilingFinished:
Holger Hildebrandtf7459252022-01-03 16:10:37 +00003981 logger.Debugw(ctx, "reconciling finished signal received",
3982 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
3983 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
3984 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
3985 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
3986 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
3987 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
3988 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
3989 // However, a later refactoring of the functionality remains unaffected.
3990 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003991 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003992 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05303993 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003994 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05303995 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00003996 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003997 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05303998 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003999 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4000 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304001 operState = voltha.OperStatus_ACTIVE
4002 } else {
4003 operState = voltha.OperStatus_ACTIVATING
4004 }
4005 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004006 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4007 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4008 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304009 operState = voltha.OperStatus_DISCOVERED
4010 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004011 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004012 logger.Debugw(ctx, "Core DeviceStateUpdate",
4013 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304014 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004015 logger.Debugw(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004016 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004017 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004018 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004019 ConnStatus: connectStatus,
4020 OperStatus: operState,
4021 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304022 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004023 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304024 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004025 } else {
Maninderb5187552021-03-23 22:23:42 +05304026 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004027 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304028
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004029 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304030 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004031 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004032 } else {
4033 onuDevEntry.MutexPersOnuConfig.RLock()
4034 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4035 connectStatus = voltha.ConnectStatus_REACHABLE
4036 }
4037 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304038 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004039 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004040 }
mpagenko101ac942021-11-16 15:01:29 +00004041 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004042 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004043 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004044 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304045
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004046 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304047 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004048 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004049 } else {
4050 onuDevEntry.MutexPersOnuConfig.RLock()
4051 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4052 connectStatus = voltha.ConnectStatus_REACHABLE
4053 }
4054 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304055 }
4056
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004057 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304058
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004059 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004060 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004061 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004062 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004063 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004064
4065 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4066 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4067 } else {
4068 onuDevEntry.MutexReconciledTpInstances.Lock()
4069 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
4070 onuDevEntry.MutexReconciledTpInstances.Unlock()
4071 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004072 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004073 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004074 dh.mutexReconcilingFlag.Lock()
4075 if skipOnuConfig {
4076 dh.reconciling = cSkipOnuConfigReconciling
4077 } else {
4078 dh.reconciling = cOnuConfigReconciling
4079 }
4080 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004081}
4082
mpagenko101ac942021-11-16 15:01:29 +00004083func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004084 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
4085 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004086 dh.sendChReconcileFinished(success)
4087 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4088 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4089 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004090 } else {
mpagenko101ac942021-11-16 15:01:29 +00004091 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004092 }
4093}
4094
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004095func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004096 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004097 defer dh.mutexReconcilingFlag.RUnlock()
4098 return dh.reconciling != cNoReconciling
4099}
4100
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004101func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004102 dh.mutexReconcilingFlag.RLock()
4103 defer dh.mutexReconcilingFlag.RUnlock()
4104 return dh.reconciling == cSkipOnuConfigReconciling
4105}
4106
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004107func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4108 dh.mutexReconcilingFirstPassFlag.Lock()
4109 dh.reconcilingFirstPass = value
4110 dh.mutexReconcilingFirstPassFlag.Unlock()
4111}
4112
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004113func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4114 dh.mutexReconcilingReasonUpdate.Lock()
4115 dh.reconcilingReasonUpdate = value
4116 dh.mutexReconcilingReasonUpdate.Unlock()
4117}
4118
4119func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4120 dh.mutexReconcilingReasonUpdate.RLock()
4121 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4122 return dh.reconcilingReasonUpdate
4123}
4124
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004125func (dh *deviceHandler) getDeviceReason() uint8 {
4126 dh.mutexDeviceReason.RLock()
4127 value := dh.deviceReason
4128 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004129 return value
4130}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004131
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004132func (dh *deviceHandler) GetDeviceReasonString() string {
4133 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004134}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004135
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004136func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004137 dh.mutexReadyForOmciConfig.Lock()
4138 dh.readyForOmciConfig = flagValue
4139 dh.mutexReadyForOmciConfig.Unlock()
4140}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004141func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004142 dh.mutexReadyForOmciConfig.RLock()
4143 flagValue := dh.readyForOmciConfig
4144 dh.mutexReadyForOmciConfig.RUnlock()
4145 return flagValue
4146}
Maninder7961d722021-06-16 22:10:28 +05304147
4148func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004149 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304150 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004151 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304152 }
4153
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004154 logger.Debugw(ctx, "Core DeviceStateUpdate",
4155 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004156 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004157 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004158 ConnStatus: connectStatus,
4159 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4160 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304161 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004162 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304163 }
4164}
khenaidoo7d3c5582021-08-11 18:09:44 -04004165
4166/*
4167Helper functions to communicate with Core
4168*/
4169
4170func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4171 cClient, err := dh.coreClient.GetCoreServiceClient()
4172 if err != nil || cClient == nil {
4173 return nil, err
4174 }
4175 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4176 defer cancel()
4177 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4178 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4179}
4180
khenaidoo42dcdfd2021-10-19 17:34:12 -04004181func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004182 cClient, err := dh.coreClient.GetCoreServiceClient()
4183 if err != nil || cClient == nil {
4184 return err
4185 }
4186 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4187 defer cancel()
4188 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004189 logger.Debugw(subCtx, "device-updated-in-core",
4190 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004191 return err
4192}
4193
4194func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4195 cClient, err := dh.coreClient.GetCoreServiceClient()
4196 if err != nil || cClient == nil {
4197 return err
4198 }
4199 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4200 defer cancel()
4201 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004202 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4203 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004204 return err
4205}
4206
4207func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4208 cClient, err := dh.coreClient.GetCoreServiceClient()
4209 if err != nil || cClient == nil {
4210 return err
4211 }
4212 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4213 defer cancel()
4214 _, err = cClient.DeviceUpdate(subCtx, device)
4215 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4216 return err
4217}
4218
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004219func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004220 cClient, err := dh.coreClient.GetCoreServiceClient()
4221 if err != nil || cClient == nil {
4222 return err
4223 }
4224 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4225 defer cancel()
4226 _, err = cClient.PortCreated(subCtx, port)
4227 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4228 return err
4229}
4230
khenaidoo42dcdfd2021-10-19 17:34:12 -04004231func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004232 cClient, err := dh.coreClient.GetCoreServiceClient()
4233 if err != nil || cClient == nil {
4234 return err
4235 }
4236 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4237 defer cancel()
4238 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004239 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 -04004240 return err
4241}
4242
khenaidoo42dcdfd2021-10-19 17:34:12 -04004243func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004244 cClient, err := dh.coreClient.GetCoreServiceClient()
4245 if err != nil || cClient == nil {
4246 return err
4247 }
4248 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4249 defer cancel()
4250 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004251 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 -04004252 return err
4253}
4254
4255/*
4256Helper functions to communicate with parent adapter
4257*/
4258
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004259func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4260 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4261
4262 var request = ia.TechProfileInstanceRequestMessage{
4263 DeviceId: dh.DeviceID,
4264 TpInstancePath: aTpPath,
4265 ParentDeviceId: dh.parentID,
4266 ParentPonPort: dh.device.ParentPortNo,
4267 OnuId: dh.device.ProxyAddress.OnuId,
4268 UniId: uint32(aUniID),
4269 }
4270
4271 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004272 if err != nil || pgClient == nil {
4273 return nil, err
4274 }
4275 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4276 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004277 logger.Debugw(subCtx, "get-tech-profile-instance",
4278 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004279 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004280}
4281
Girish Gowdrae95687a2021-09-08 16:30:58 -07004282// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4283// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4284func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4285 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4286 dh.setFlowMonitoringIsRunning(uniID, true)
4287 for {
4288 select {
4289 // block on the channel to receive an incoming flow
4290 // process the flow completely before proceeding to handle the next flow
4291 case flowCb := <-dh.flowCbChan[uniID]:
4292 startTime := time.Now()
4293 logger.Debugw(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
4294 respChan := make(chan error)
4295 if flowCb.addFlow {
4296 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4297 } else {
4298 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4299 }
4300 // Block on response and tunnel it back to the caller
4301 *flowCb.respChan <- <-respChan
4302 logger.Debugw(flowCb.ctx, "serial-flow-processor--end",
4303 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4304 case <-dh.stopFlowMonitoringRoutine[uniID]:
4305 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4306 dh.setFlowMonitoringIsRunning(uniID, false)
4307 return
4308 }
4309 }
4310}
4311
khenaidoo42dcdfd2021-10-19 17:34:12 -04004312func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004313 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4314 if err != nil || pgClient == nil {
4315 return err
4316 }
4317 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4318 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004319 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004320 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4321 if err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004322 logger.Errorw(ctx, "omci-failure",
4323 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
4324 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
khenaidoo7d3c5582021-08-11 18:09:44 -04004325 }
4326 return err
4327}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004328
4329// GetDeviceID - TODO: add comment
4330func (dh *deviceHandler) GetDeviceID() string {
4331 return dh.DeviceID
4332}
4333
4334// GetProxyAddressID - TODO: add comment
4335func (dh *deviceHandler) GetProxyAddressID() string {
4336 return dh.device.ProxyAddress.GetDeviceId()
4337}
4338
4339// GetProxyAddressType - TODO: add comment
4340func (dh *deviceHandler) GetProxyAddressType() string {
4341 return dh.device.ProxyAddress.GetDeviceType()
4342}
4343
4344// GetProxyAddress - TODO: add comment
4345func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4346 return dh.device.ProxyAddress
4347}
4348
4349// GetEventProxy - TODO: add comment
4350func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4351 return dh.EventProxy
4352}
4353
4354// GetOmciTimeout - TODO: add comment
4355func (dh *deviceHandler) GetOmciTimeout() int {
4356 return dh.pOpenOnuAc.omciTimeout
4357}
4358
4359// GetAlarmAuditInterval - TODO: add comment
4360func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4361 return dh.pOpenOnuAc.alarmAuditInterval
4362}
4363
4364// GetDlToOnuTimeout4M - TODO: add comment
4365func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4366 return dh.pOpenOnuAc.dlToOnuTimeout4M
4367}
4368
4369// GetUniEntityMap - TODO: add comment
4370func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4371 return &dh.uniEntityMap
4372}
4373
4374// GetPonPortNumber - TODO: add comment
4375func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4376 return &dh.ponPortNumber
4377}
4378
4379// GetUniVlanConfigFsm - TODO: add comment
4380func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004381 dh.lockVlanConfig.RLock()
4382 value := dh.UniVlanConfigFsmMap[uniID]
4383 dh.lockVlanConfig.RUnlock()
4384 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004385}
4386
4387// GetOnuAlarmManager - TODO: add comment
4388func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4389 return dh.pAlarmMgr
4390}
4391
4392// GetOnuMetricsManager - TODO: add comment
4393func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4394 return dh.pOnuMetricsMgr
4395}
4396
4397// GetOnuTP - TODO: add comment
4398func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4399 return dh.pOnuTP
4400}
4401
4402// GetBackendPathPrefix - TODO: add comment
4403func (dh *deviceHandler) GetBackendPathPrefix() string {
4404 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4405}
4406
4407// GetOnuIndication - TODO: add comment
4408func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4409 return dh.pOnuIndication
4410}
4411
4412// RLockMutexDeletionInProgressFlag - TODO: add comment
4413func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4414 dh.mutexDeletionInProgressFlag.RLock()
4415}
4416
4417// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4418func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4419 dh.mutexDeletionInProgressFlag.RUnlock()
4420}
4421
4422// GetDeletionInProgress - TODO: add comment
4423func (dh *deviceHandler) GetDeletionInProgress() bool {
4424 return dh.deletionInProgress
4425}
4426
4427// GetPmConfigs - TODO: add comment
4428func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4429 return dh.pmConfigs
4430}
4431
4432// GetDeviceType - TODO: add comment
4433func (dh *deviceHandler) GetDeviceType() string {
4434 return dh.DeviceType
4435}
4436
4437// GetLogicalDeviceID - TODO: add comment
4438func (dh *deviceHandler) GetLogicalDeviceID() string {
4439 return dh.logicalDeviceID
4440}
4441
4442// GetDevice - TODO: add comment
4443func (dh *deviceHandler) GetDevice() *voltha.Device {
4444 return dh.device
4445}
4446
4447// GetMetricsEnabled - TODO: add comment
4448func (dh *deviceHandler) GetMetricsEnabled() bool {
4449 return dh.pOpenOnuAc.MetricsEnabled
4450}
4451
4452// InitPmConfigs - TODO: add comment
4453func (dh *deviceHandler) InitPmConfigs() {
4454 dh.pmConfigs = &voltha.PmConfigs{}
4455}
4456
4457// GetUniPortMask - TODO: add comment
4458func (dh *deviceHandler) GetUniPortMask() int {
4459 return dh.pOpenOnuAc.config.UniPortMask
4460}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00004461
4462func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
4463 tpPathFound := false
4464 for _, tpPath := range aTpPathMap {
4465 if tpPath != "" {
4466 tpPathFound = true
4467 }
4468 }
4469 return tpPathFound
4470}