blob: 332f776d6976f239632cc25e19ca24c0b09a22a5 [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000017//Package core provides the utility for onu devices, flows and statistics
18package core
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000019
20import (
21 "context"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000022 "errors"
23 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000024 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000025 "sync"
26 "time"
27
khenaidoo7d3c5582021-08-11 18:09:44 -040028 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/config"
mpagenko1f8e8822021-06-25 14:10:21 +000029
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000030 "github.com/gogo/protobuf/proto"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000031 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000032 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040033 "github.com/opencord/voltha-lib-go/v7/pkg/db"
34 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
35 flow "github.com/opencord/voltha-lib-go/v7/pkg/flows"
36 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
37 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Mahir Gunyelcb128ae2021-10-06 09:42:05 -070038 platform "github.com/opencord/voltha-lib-go/v7/pkg/platform"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000039 almgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/almgr"
40 avcfg "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/avcfg"
41 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
42 mib "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/mib"
43 otst "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/omcitst"
44 pmmgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/pmmgr"
45 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/swupg"
46 uniprt "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/uniprt"
khenaidoo7d3c5582021-08-11 18:09:44 -040047 vc "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo42dcdfd2021-10-19 17:34:12 -040048 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040049 "github.com/opencord/voltha-protos/v5/go/extension"
Holger Hildebrandt9afc1582021-11-30 16:10:19 +000050 "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo42dcdfd2021-10-19 17:34:12 -040051 ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040052 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
mpagenko59862f02021-10-11 08:53:18 +000053 "github.com/opencord/voltha-protos/v5/go/openolt"
khenaidoo7d3c5582021-08-11 18:09:44 -040054 oop "github.com/opencord/voltha-protos/v5/go/openolt"
mpagenko59862f02021-10-11 08:53:18 +000055 "github.com/opencord/voltha-protos/v5/go/tech_profile"
khenaidoo7d3c5582021-08-11 18:09:44 -040056 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000057)
58
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000059const (
mpagenko101ac942021-11-16 15:01:29 +000060 //constants for reconcile flow check channel
61 cWaitReconcileFlowAbortOnSuccess = 0xFFFD
62 cWaitReconcileFlowAbortOnError = 0xFFFE
63 cWaitReconcileFlowNoActivity = 0xFFFF
64)
65
66const (
67 // constants for timeouts
mpagenko38662d02021-08-11 09:45:19 +000068 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000069)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000070
mpagenko1cc3cb42020-07-27 15:24:38 +000071const (
mpagenko44bd8362021-11-15 11:40:05 +000072 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
73 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
74 // as long as such is not available by the libraries - use this workaround
75 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
76)
77
78const (
mpagenko1cc3cb42020-07-27 15:24:38 +000079 // events of Device FSM
80 devEvDeviceInit = "devEvDeviceInit"
81 devEvGrpcConnected = "devEvGrpcConnected"
82 devEvGrpcDisconnected = "devEvGrpcDisconnected"
83 devEvDeviceUpInd = "devEvDeviceUpInd"
84 devEvDeviceDownInd = "devEvDeviceDownInd"
85)
86const (
87 // states of Device FSM
88 devStNull = "devStNull"
89 devStDown = "devStDown"
90 devStInit = "devStInit"
91 devStConnected = "devStConnected"
92 devStUp = "devStUp"
93)
94
Holger Hildebrandt24d51952020-05-04 14:03:42 +000095//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
96const (
Himani Chawla4d908332020-08-31 12:30:20 +053097 pon = voltha.EventSubCategory_PON
98 //olt = voltha.EventSubCategory_OLT
99 //ont = voltha.EventSubCategory_ONT
100 //onu = voltha.EventSubCategory_ONU
101 //nni = voltha.EventSubCategory_NNI
102 //service = voltha.EventCategory_SERVICE
103 //security = voltha.EventCategory_SECURITY
104 equipment = voltha.EventCategory_EQUIPMENT
105 //processing = voltha.EventCategory_PROCESSING
106 //environment = voltha.EventCategory_ENVIRONMENT
107 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000108)
109
110const (
111 cEventObjectType = "ONU"
112)
113const (
114 cOnuActivatedEvent = "ONU_ACTIVATED"
115)
116
mpagenkof1fc3862021-02-16 10:09:52 +0000117type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000118 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000119 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000120}
121
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000122var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
123 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
124 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
125 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
126 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
127 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
128 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
129 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
130 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000131}
132
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000133const (
134 cNoReconciling = iota
135 cOnuConfigReconciling
136 cSkipOnuConfigReconciling
137)
138
Girish Gowdrae95687a2021-09-08 16:30:58 -0700139// FlowCb is the flow control block containing flow add/delete information along with a response channel
140type FlowCb struct {
141 ctx context.Context // Flow handler context
142 addFlow bool // if true flow to be added, else removed
143 flowItem *of.OfpFlowStats
144 uniPort *cmn.OnuUniPort
khenaidoo42dcdfd2021-10-19 17:34:12 -0400145 flowMetaData *of.FlowMetadata
Girish Gowdrae95687a2021-09-08 16:30:58 -0700146 respChan *chan error // channel to report the Flow handling error
147}
148
Himani Chawla6d2ae152020-09-02 13:11:20 +0530149//deviceHandler will interact with the ONU ? device.
150type deviceHandler struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000151 DeviceID string
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000152 DeviceType string
153 adminState string
154 device *voltha.Device
155 logicalDeviceID string
156 ProxyAddressID string
157 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530158 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000159 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000160
khenaidoo7d3c5582021-08-11 18:09:44 -0400161 coreClient *vgrpc.Client
162 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000163
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800164 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400165 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800166
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000167 pOpenOnuAc *OpenONUAC
168 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530169 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000170 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000171 pOnuOmciDevice *mib.OnuDeviceEntry
172 pOnuTP *avcfg.OnuUniTechProf
173 pOnuMetricsMgr *pmmgr.OnuMetricsManager
174 pAlarmMgr *almgr.OnuAlarmManager
175 pSelfTestHdlr *otst.SelfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000176 exitChannel chan int
177 lockDevice sync.RWMutex
178 pOnuIndication *oop.OnuIndication
179 deviceReason uint8
180 mutexDeviceReason sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000181 pLockStateFsm *uniprt.LockStateFsm
182 pUnlockStateFsm *uniprt.LockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000183
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000184 //flowMgr *OpenOltFlowMgr
185 //eventMgr *OpenOltEventMgr
186 //resourceMgr *rsrcMgr.OpenOltResourceMgr
187
188 //discOnus sync.Map
189 //onus sync.Map
190 //portStats *OpenOltStatisticsMgr
mpagenko101ac942021-11-16 15:01:29 +0000191 collectorIsRunning bool
192 mutexCollectorFlag sync.RWMutex
193 stopCollector chan bool
194 alarmManagerIsRunning bool
195 mutextAlarmManagerFlag sync.RWMutex
196 stopAlarmManager chan bool
197 stopHeartbeatCheck chan bool
198 uniEntityMap cmn.OnuUniPortMap
199 mutexKvStoreContext sync.Mutex
200 lockVlanConfig sync.RWMutex
201 lockVlanAdd sync.RWMutex
202 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
203 lockUpgradeFsm sync.RWMutex
204 pOnuUpradeFsm *swupg.OnuUpgradeFsm
205 upgradeCanceled bool
206 reconciling uint8
207 mutexReconcilingFlag sync.RWMutex
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000208 reconcilingFirstPass bool
209 mutexReconcilingFirstPassFlag sync.RWMutex
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000210 reconcilingReasonUpdate bool
211 mutexReconcilingReasonUpdate sync.RWMutex
mpagenko101ac942021-11-16 15:01:29 +0000212 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
213 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
214 reconcileExpiryComplete time.Duration
215 reconcileExpiryVlanConfig time.Duration
216 mutexReadyForOmciConfig sync.RWMutex
217 readyForOmciConfig bool
218 deletionInProgress bool
219 mutexDeletionInProgressFlag sync.RWMutex
220 pLastUpgradeImageState *voltha.ImageState
221 upgradeFsmChan chan struct{}
Girish Gowdrae95687a2021-09-08 16:30:58 -0700222
223 flowCbChan []chan FlowCb
224 mutexFlowMonitoringRoutineFlag sync.RWMutex
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300225 mutexForDisableDeviceRequested sync.RWMutex
Girish Gowdrae95687a2021-09-08 16:30:58 -0700226 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
227 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300228 disableDeviceRequested bool // this flag identify ONU received disable request or not
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000229}
230
Himani Chawla6d2ae152020-09-02 13:11:20 +0530231//newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400232func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530233 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400234 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000235 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400236 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000237 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000238 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000239 dh.DeviceType = cloned.Type
240 dh.adminState = "up"
241 dh.device = cloned
242 dh.pOpenOnuAc = adapter
243 dh.exitChannel = make(chan int, 1)
244 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000245 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000246 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000247 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530248 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530249 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000250 dh.stopHeartbeatCheck = make(chan bool, 2)
251 //dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000252 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000253 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000254 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000255 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000256 dh.lockUpgradeFsm = sync.RWMutex{}
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300257 dh.mutexForDisableDeviceRequested = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000258 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000259 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000260 dh.reconcilingReasonUpdate = false
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000261 dh.reconcilingFirstPass = true
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300262 dh.disableDeviceRequested = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000263 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000264 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
265 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
266 if rECSeconds < 2 {
267 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
268 rECSeconds = 2
269 }
270 rEVCSeconds := rECSeconds / 2
271 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000272 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000273 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000274 dh.pLastUpgradeImageState = &voltha.ImageState{
275 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
276 Reason: voltha.ImageState_UNKNOWN_ERROR,
277 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
278 }
279 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000280
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800281 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
282 dh.pmConfigs = cloned.PmConfigs
283 } /* else {
284 // will be populated when onu_metrics_mananger is initialized.
285 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800286
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000287 // Device related state machine
288 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000289 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000290 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000291 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
292 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
293 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
294 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
295 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000296 },
297 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000298 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
299 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
300 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
301 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
302 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
303 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
304 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
305 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000306 },
307 )
mpagenkoaf801632020-07-03 10:00:42 +0000308
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000309 return &dh
310}
311
Himani Chawla6d2ae152020-09-02 13:11:20 +0530312// start save the device to the data model
313func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000314 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000315 // Add the initial device to the local model
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000316 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000317}
318
Himani Chawla4d908332020-08-31 12:30:20 +0530319/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000320// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530321func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000322 logger.Debug("stopping-device-handler")
323 dh.exitChannel <- 1
324}
Himani Chawla4d908332020-08-31 12:30:20 +0530325*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000326
327// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530328// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000329
Girish Gowdrae0140f02021-02-02 16:55:09 -0800330//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530331func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400332 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000333
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000334 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000335 if dh.pDeviceStateFsm.Is(devStNull) {
336 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000337 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"device-id": device.Id, "err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000338 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000339 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800340 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
341 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800342 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400343 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000344 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800345 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800346 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000347 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000348 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000349 }
350
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000351}
352
khenaidoo42dcdfd2021-10-19 17:34:12 -0400353func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000354 /* msg print moved symmetrically to omci_cc, if wanted here as additional debug, than perhaps only based on additional debug setting!
Himani Chawla26e555c2020-08-31 12:30:20 +0530355 //assuming omci message content is hex coded!
356 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000357 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000358 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000359 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000360 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530361 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000362 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000363 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000364 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000365 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
366 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530367 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000368 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
369 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530370}
371
khenaidoo42dcdfd2021-10-19 17:34:12 -0400372func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000373 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000374
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000375 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000376 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000377 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
378 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000379 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530380 if dh.pOnuTP == nil {
381 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000382 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000383 log.Fields{"device-id": dh.DeviceID})
384 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530385 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000386 if !dh.IsReadyForOmciConfig() {
387 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
388 "device-state": dh.GetDeviceReasonString()})
389 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530390 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000391 //previous state test here was just this one, now extended for more states to reject the SetRequest:
392 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
393 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530394
Himani Chawla26e555c2020-08-31 12:30:20 +0530395 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000396 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
397 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000398 dh.pOnuTP.LockTpProcMutex()
399 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000400
mpagenko44bd8362021-11-15 11:40:05 +0000401 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000402 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000403 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000404 }
405 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000406 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800407 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700408 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800409 return err
410 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000411 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
412 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000413
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000414 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530415
Girish Gowdra50e56422021-06-01 16:46:04 -0700416 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400417 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000418 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
419 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700420 // if there has been some change for some uni TechProfilePath
421 //in order to allow concurrent calls to other dh instances we do not wait for execution here
422 //but doing so we can not indicate problems to the caller (who does what with that then?)
423 //by now we just assume straightforward successful execution
424 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
425 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530426
Girish Gowdra50e56422021-06-01 16:46:04 -0700427 // deadline context to ensure completion of background routines waited for
428 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
429 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
430 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000431
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000432 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700433
434 var wg sync.WaitGroup
435 wg.Add(1) // for the 1 go routine to finish
436 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000437 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700438 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000439 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
440 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.DeviceID, "err": tpErr, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700441 return tpErr
442 }
443 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
444 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000445 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700446 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000447 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700448 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000449 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
450 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.DeviceID, "err": kvErr, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700451 return kvErr
452 }
453 return nil
454 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000455 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700456 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700457 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530458 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000459 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000460 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
461 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530462 return nil
463}
464
khenaidoo42dcdfd2021-10-19 17:34:12 -0400465func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000466 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530467
468 if dh.pOnuTP == nil {
469 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000470 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000471 log.Fields{"device-id": dh.DeviceID})
472 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530473 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530474 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000475 dh.pOnuTP.LockTpProcMutex()
476 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530477
mpagenko0f543222021-11-03 16:24:14 +0000478 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
479 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
480 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000481 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000482 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000483 }
484 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000485 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800486 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000487 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
488 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800489 return err
490 }
mpagenko0f543222021-11-03 16:24:14 +0000491 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
492 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000493 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000494
Mahir Gunyel9545be22021-07-04 15:53:16 -0700495 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000496 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000497
Himani Chawla26e555c2020-08-31 12:30:20 +0530498}
499
khenaidoo42dcdfd2021-10-19 17:34:12 -0400500func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000501 logger.Infow(ctx, "delete-tcont-request start", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000502
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000503 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000504 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000505 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
506 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000507 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530508 if dh.pOnuTP == nil {
509 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000510 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000511 log.Fields{"device-id": dh.DeviceID})
512 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530513 }
514
Himani Chawla26e555c2020-08-31 12:30:20 +0530515 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000516 dh.pOnuTP.LockTpProcMutex()
517 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000518
mpagenko0f543222021-11-03 16:24:14 +0000519 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
520 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
521 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000522 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000523 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000524 }
525 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700526 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000527 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800528 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000529 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
530 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800531 return err
532 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000533 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 +0000534
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000535 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530536
Mahir Gunyel9545be22021-07-04 15:53:16 -0700537 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000538 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000539
Mahir Gunyel9545be22021-07-04 15:53:16 -0700540}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000541
Mahir Gunyel9545be22021-07-04 15:53:16 -0700542func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000543 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
544 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700545 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000546 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
547 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530548 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700549 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000550 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700551 resourceName = "Gem"
552 } else {
553 resourceName = "Tcont"
554 }
555
556 // deadline context to ensure completion of background routines waited for
557 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
558 dctx, cancel := context.WithDeadline(context.Background(), deadline)
559
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000560 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700561
562 var wg sync.WaitGroup
563 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000564 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700565 resource, entryID, &wg)
566 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000567 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
568 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700569 return err
570 }
571
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000572 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
573 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
574 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
575 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700576 var wg2 sync.WaitGroup
577 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
578 wg2.Add(1)
579 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000580 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
581 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700582 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000583 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
584 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700585 return err
586 }
587 }
588 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000589 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700590 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530591 return nil
592}
593
mpagenkodff5dda2020-08-28 11:52:01 +0000594//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000595func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400596 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400597 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700598 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
599 var errorsList []error
600 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000601 //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 +0000602 if apOfFlowChanges.ToRemove != nil {
603 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000604 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000605 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000606 "device-id": dh.DeviceID})
607 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700608 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000609 continue
610 }
611 flowInPort := flow.GetInPort(flowItem)
612 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000613 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
614 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700615 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000616 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000617 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000618 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000619 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000620 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000621 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000622 continue
623 } else {
624 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000625 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000626 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
627 loUniPort = uniPort
628 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000629 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000630 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000631 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000632 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700633 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000634 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000635 }
636 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000637 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000638 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
639 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700640
641 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
642 // Step1 : Fill flowControlBlock
643 // Step2 : Push the flowControlBlock to ONU channel
644 // Step3 : Wait on response channel for response
645 // Step4 : Return error value
646 startTime := time.Now()
647 respChan := make(chan error)
648 flowCb := FlowCb{
649 ctx: ctx,
650 addFlow: false,
651 flowItem: flowItem,
652 flowMetaData: nil,
653 uniPort: loUniPort,
654 respChan: &respChan,
655 }
656 dh.flowCbChan[loUniPort.UniID] <- flowCb
657 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
658 // Wait on the channel for flow handlers return value
659 retError = <-respChan
660 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
661 if retError != nil {
662 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
663 log.Fields{"device-id": dh.DeviceID, "error": retError})
664 errorsList = append(errorsList, retError)
665 continue
666 }
667 } else {
668 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
669 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000670 }
671 }
672 }
673 }
mpagenko01e726e2020-10-23 09:45:29 +0000674 if apOfFlowChanges.ToAdd != nil {
675 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
676 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000677 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000678 "device-id": dh.DeviceID})
679 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700680 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000681 continue
682 }
683 flowInPort := flow.GetInPort(flowItem)
684 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000685 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
686 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700687 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000688 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000689 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000690 } else if flowInPort == dh.ponPortNumber {
691 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000692 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000693 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000694 continue
695 } else {
696 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000697 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000698 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
699 loUniPort = uniPort
700 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000701 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000702 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000703 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000704 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700705 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000706 continue
mpagenko01e726e2020-10-23 09:45:29 +0000707 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000708 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
709 // if not, we just throw some error here to have an indication about that, if we really need to support that
710 // then we would need to create some means to activate the internal stored flows
711 // after the device gets active automatically (and still with its dependency to the TechProfile)
712 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
713 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000714 if !dh.IsReadyForOmciConfig() {
715 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
716 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700717 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
718 errorsList = append(errorsList, retError)
719 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000720 }
721
mpagenko01e726e2020-10-23 09:45:29 +0000722 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000723 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000724 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
725 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700726 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
727 // Step1 : Fill flowControlBlock
728 // Step2 : Push the flowControlBlock to ONU channel
729 // Step3 : Wait on response channel for response
730 // Step4 : Return error value
731 startTime := time.Now()
732 respChan := make(chan error)
733 flowCb := FlowCb{
734 ctx: ctx,
735 addFlow: true,
736 flowItem: flowItem,
737 flowMetaData: apFlowMetaData,
738 uniPort: loUniPort,
739 respChan: &respChan,
740 }
741 dh.flowCbChan[loUniPort.UniID] <- flowCb
742 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
743 // Wait on the channel for flow handlers return value
744 retError = <-respChan
745 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
746 if retError != nil {
747 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
748 log.Fields{"device-id": dh.DeviceID, "error": retError})
749 errorsList = append(errorsList, retError)
750 continue
751 }
752 } else {
753 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
754 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000755 }
756 }
757 }
758 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700759 if len(errorsList) > 0 {
760 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
761 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
762 }
763 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000764}
765
Himani Chawla6d2ae152020-09-02 13:11:20 +0530766//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000767//following are the expected device states after this activity:
768//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
769// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000770func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
771 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300772 dh.mutexForDisableDeviceRequested.Lock()
773 dh.disableDeviceRequested = true
774 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000775 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000776 //note that disableDevice sequences in some 'ONU active' state may yield also
777 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000778 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000779 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000780 //disable-device shall be just a UNi/ONU-G related admin state setting
781 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000782
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000783 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000784 // disable UNI ports/ONU
785 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
786 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000787 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000788 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000789 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000790 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000791 }
792 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000793 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000794 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000795 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400796 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000797 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000798 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400799 OperStatus: voltha.OperStatus_UNKNOWN,
800 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000801 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000802 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000803 }
mpagenko01e726e2020-10-23 09:45:29 +0000804 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000805
806 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000807 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000808 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300809 }
810}
811
Himani Chawla6d2ae152020-09-02 13:11:20 +0530812//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000813func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
814 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000815
mpagenkoaa3afe92021-05-21 16:20:58 +0000816 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000817 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
818 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
819 // for real ONU's that should have nearly no influence
820 // Note that for real ONU's there is anyway a problematic situation with following sequence:
821 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
822 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
823 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000824 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000825
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000826 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000827 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300828 dh.mutexForDisableDeviceRequested.Lock()
829 dh.disableDeviceRequested = false
830 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000831 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000832 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000833 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000834 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000835 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000836 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300837}
838
dbainbri4d3a0dc2020-12-02 00:33:42 +0000839func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000840 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000841
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000842 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000843 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000844 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000845 return
846 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000847 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000848 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000849 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000850 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000851 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000852 }
mpagenko101ac942021-11-16 15:01:29 +0000853 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000854 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000855 }
Himani Chawla4d908332020-08-31 12:30:20 +0530856 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000857 pDevEntry.MutexPersOnuConfig.RLock()
858 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
859 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
860 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
861 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
862 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000863 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000864}
865
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000866func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000867 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000868
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000869 continueWithFlowConfig := false
870
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000871 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000872 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000873 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000874 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
875 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000876 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000877 dh.pOnuTP.LockTpProcMutex()
878 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000879
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000880 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000881 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000882 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
883 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000884 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000885 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000886 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
887 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000888 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000889 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700890 techProfsFound := false
891 techProfInstLoadFailed := false
892outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000893 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000894 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000895 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000896 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000897 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000898 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000899 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000900 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000901 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
902 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000903 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000904 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000905 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700906 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000907 var iaTechTpInst ia.TechProfileDownloadMessage
908 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800909 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000910 pDevEntry.MutexReconciledTpInstances.RLock()
911 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
912 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000913 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000914 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700915 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000916 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700917 break outerLoop
918 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000919 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000920 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700921 var tpInst tech_profile.TechProfileInstance
922 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400923 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700924 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000925 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000926 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700927 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000928 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000929 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700930 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
931 break outerLoop
932 }
933
Girish Gowdra041dcb32020-11-16 16:54:30 -0800934 // deadline context to ensure completion of background routines waited for
935 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
936 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000937 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000938
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000939 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800940 var wg sync.WaitGroup
941 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000942 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000943 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000944 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
945 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700946 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
947 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800948 }
mpagenko2dc896e2021-08-02 12:03:59 +0000949 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000950 if len(uniData.PersFlowParams) != 0 {
951 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000952 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000953 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000954 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000955 } // for all UNI entries from SOnuPersistentData
956 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
957 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000958 }
mpagenko2dc896e2021-08-02 12:03:59 +0000959
960 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
961 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000962
963 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +0000964}
965
966func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
967 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
968 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000969 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000970 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000971 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000972 return
973 }
mpagenko2dc896e2021-08-02 12:03:59 +0000974 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000975 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +0000976 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -0700977 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000978 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000979 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000980 }
mpagenko2dc896e2021-08-02 12:03:59 +0000981 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000982 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000983 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000984 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000985 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000986}
987
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000988func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
989 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000990
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000991 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000992 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000993 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000994 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000995 return
996 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000997
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000998 pDevEntry.MutexPersOnuConfig.RLock()
999 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1000 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001001 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001002 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001003 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001004 return
1005 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001006 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001007 var uniVlanConfigEntries []uint8
1008 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1009
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001010 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001011 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1012 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001013 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001014 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001015 continue
1016 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001017 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001018 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001019 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001020 // It doesn't make sense to configure any flows if no TPs are available
1021 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001022 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001023 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1024 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001025 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001026 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001027
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001028 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001029 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001030 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001031 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001032 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1033 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001034 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001035 return
1036 }
mpagenko101ac942021-11-16 15:01:29 +00001037 //needed to split up function due to sca complexity
1038 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1039
mpagenko2dc896e2021-08-02 12:03:59 +00001040 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001041 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001042 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1043 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001044 // this can't be used as global finished reconciling flag because
1045 // assumes is getting called before the state machines for the last flow is completed,
1046 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001047 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1048 } // for all UNI entries from SOnuPersistentData
1049 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001050
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001051 if !flowsFound {
1052 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001053 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001054 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001055 return
1056 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001057 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1058 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1059 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1060 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1061 log.Fields{"device-id": dh.DeviceID})
1062 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1063 if pDevEntry != nil {
1064 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001065 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001066 } else {
1067 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1068 log.Fields{"device-id": dh.DeviceID})
1069 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1070 if pDevEntry != nil {
1071 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1072 }
1073 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001074 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001075 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001076}
1077
mpagenko101ac942021-11-16 15:01:29 +00001078func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1079 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1080 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1081 flowsProcessed := 0
1082 lastFlowToReconcile := false
1083 loUniID := apUniPort.UniID
1084 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001085 if !(*apFlowsFound) {
1086 *apFlowsFound = true
1087 syncChannel := make(chan struct{})
1088 // start go routine with select() on reconciling vlan config channel before
1089 // starting vlan config reconciling process to prevent loss of any signal
1090 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1091 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1092 //block until the wait routine is really blocked on channel input
1093 // in order to prevent to early ready signal from VlanConfig processing
1094 <-syncChannel
1095 }
1096 if flowsProcessed == len(aPersFlowParam)-1 {
1097 var uniAdded bool
1098 lastFlowToReconcile = true
1099 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1100 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001101 }
1102 }
mpagenko101ac942021-11-16 15:01:29 +00001103 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1104 "device-id": dh.DeviceID, "uni-id": loUniID,
1105 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1106 dh.lockVlanConfig.Lock()
1107 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1108 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1109 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
1110 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1111 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter, nil); err != nil {
1112 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1113 }
1114 } else {
1115 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
1116 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1117 uint8(flowData.VlanRuleParams.SetPcp), cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
1118 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1119 }
1120 }
1121 dh.lockVlanConfig.Unlock()
1122 flowsProcessed++
1123 } //for all flows of this UNI
1124}
1125
1126//waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1127// and decrements the according handler wait group waiting for these indications
1128func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1129 waitGroup *cmn.WaitGroupWithTimeOut) {
1130 var reconciledUniVlanConfigEntries []uint8
1131 var appended bool
1132 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1133 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1134 "device-id": dh.DeviceID, "expiry": expiry})
1135 // indicate blocking on channel now to the caller
1136 aSyncChannel <- struct{}{}
1137 for {
1138 select {
1139 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1140 switch uniIndication {
1141 // no activity requested (should normally not be received) - just continue waiting
1142 case cWaitReconcileFlowNoActivity:
1143 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1144 case cWaitReconcileFlowAbortOnError:
1145 logger.Debugw(ctx, "waitReconcileFlow aborted on error",
1146 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1147 return
1148 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1149 case cWaitReconcileFlowAbortOnSuccess:
1150 logger.Debugw(ctx, "waitReconcileFlow aborted on success",
1151 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1152 return
1153 // this should be a valid UNI vlan config done indication
1154 default:
1155 if uniIndication < platform.MaxUnisPerOnu {
1156 logger.Debugw(ctx, "reconciling flows has been finished in time for this UNI",
1157 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1158 if reconciledUniVlanConfigEntries, appended =
1159 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1160 waitGroup.Done()
1161 }
1162 } else {
1163 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored",
1164 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1165 }
1166 } //switch uniIndication
1167
1168 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1169 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1170 log.Fields{"device-id": dh.DeviceID})
1171 return
1172 }
1173 }
1174}
1175
1176func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1177 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1178}
1179
1180func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1181 for _, ele := range slice {
1182 if ele == val {
1183 return slice, false
1184 }
1185 }
1186 return append(slice, val), true
1187}
1188
1189// sendChReconcileFinished - sends true or false on reconcileFinish channel
1190func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1191 if dh != nil { //if the object still exists (might have been already deleted in background)
1192 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1193 select {
1194 case dh.chReconcilingFinished <- success:
1195 default:
1196 }
1197 }
1198}
1199
1200// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1201func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1202 if dh != nil { //if the object still exists (might have been already deleted in background)
1203 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1204 select {
1205 case dh.chUniVlanConfigReconcilingDone <- value:
1206 default:
1207 }
1208 }
1209}
1210
dbainbri4d3a0dc2020-12-02 00:33:42 +00001211func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001212 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001213
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001214 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001215 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001216 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001217 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001218 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001219 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001220
1221 // deadline context to ensure completion of background routines waited for
1222 //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 +05301223 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001224 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001225
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001226 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001227
1228 var wg sync.WaitGroup
1229 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001230 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001231 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001232
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001233 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001234 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001235}
1236
mpagenko15ff4a52021-03-02 10:09:20 +00001237//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1238// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001239// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001240//was and is called in background - error return does not make sense
1241func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001242 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001243 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001244 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001245 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001246 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001247 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301248 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001249 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001250 return
Himani Chawla4d908332020-08-31 12:30:20 +05301251 }
mpagenko01e726e2020-10-23 09:45:29 +00001252
1253 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001254 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001255
mpagenko44bd8362021-11-15 11:40:05 +00001256 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001257 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001258 // 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 -04001259 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001260 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001261 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001262 OperStatus: voltha.OperStatus_DISCOVERED,
1263 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001264 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001265 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001266 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001267 }
mpagenkoe4782082021-11-25 12:04:26 +00001268 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001269 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001270 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001271 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001272 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1273 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1274 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1275 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001276}
1277
mpagenkoc8bba412021-01-15 15:38:44 +00001278//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001279// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001280func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001281 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001282 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001283 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001284
1285 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001286 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001287 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001288 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1289 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001290 }
1291
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001292 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001293 var inactiveImageID uint16
1294 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1295 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001296 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1297 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001298 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001299 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001300 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001301 if err == nil {
1302 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1303 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001304 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001305 }
1306 } else {
1307 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001308 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001309 }
mpagenko15ff4a52021-03-02 10:09:20 +00001310 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001311 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001312 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001313 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1314 dh.upgradeCanceled = true
1315 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1316 }
mpagenko38662d02021-08-11 09:45:19 +00001317 //no effort spent anymore for the old API to automatically cancel and restart the download
1318 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001319 }
mpagenko15ff4a52021-03-02 10:09:20 +00001320 } else {
1321 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001322 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001323 }
1324 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001325 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1326 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001327 }
1328 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001329}
1330
mpagenkoc26d4c02021-05-06 14:27:57 +00001331//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1332// after the OnuImage has been downloaded to the adapter, called in background
1333func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001334 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001335
1336 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001337 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001338 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001339 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001340 return
1341 }
1342
1343 var inactiveImageID uint16
1344 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1345 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001346 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001347
mpagenko59862f02021-10-11 08:53:18 +00001348 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001349 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001350 // but must be still locked at calling createOnuUpgradeFsm
1351 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1352 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1353 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001354 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1355 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001356 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001357 //flush the remove upgradeFsmChan channel
1358 select {
1359 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001360 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001361 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001362 }
mpagenko59862f02021-10-11 08:53:18 +00001363 dh.lockUpgradeFsm.Unlock()
1364 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1365 dh.upgradeCanceled = true
1366 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1367 }
mpagenko38662d02021-08-11 09:45:19 +00001368 select {
1369 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001370 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001371 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1372 return
1373 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001374 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001375 }
mpagenko59862f02021-10-11 08:53:18 +00001376 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001377 }
mpagenko38662d02021-08-11 09:45:19 +00001378
1379 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001380 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001381 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001382 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001383 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001384 if err == nil {
1385 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1386 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1387 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001388 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001389 return
1390 }
mpagenko38662d02021-08-11 09:45:19 +00001391 } else {
1392 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001393 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001394 }
1395 return
1396 }
1397 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001398 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001399}
1400
1401//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001402func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1403 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001404 var err error
1405 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1406 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1407 // 2.) activation of the inactive image
1408
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001409 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001410 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001411 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1412 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001413 }
1414 dh.lockUpgradeFsm.RLock()
1415 if dh.pOnuUpradeFsm != nil {
1416 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001417 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001418 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001419 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1420 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001421 }
mpagenko59862f02021-10-11 08:53:18 +00001422 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1423 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1424 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1425 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001426 // use the OnuVendor identification from this device for the internal unique name
1427 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001428 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001429 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001430 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001431 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001432 "device-id": dh.DeviceID, "error": err})
1433 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001434 }
mpagenko183647c2021-06-08 15:25:04 +00001435 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001436 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001437 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001438 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001439 } //else
1440 dh.lockUpgradeFsm.RUnlock()
1441
1442 // 2.) check if requested image-version equals the inactive one and start its activation
1443 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1444 var inactiveImageID uint16
1445 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1446 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001447 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1448 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001449 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001450 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001451 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001452 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001453 if err == nil {
1454 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1455 inactiveImageID, aCommitRequest); err != nil {
1456 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001457 "device-id": dh.DeviceID, "error": err})
1458 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001459 }
1460 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001461 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001462 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001463 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001464 } //else
1465 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001466 "device-id": dh.DeviceID, "error": err})
1467 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001468}
1469
1470//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001471func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1472 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001473 var err error
1474 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1475 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1476 // 2.) commitment of the active image
1477
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001478 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001479 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001480 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1481 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001482 }
1483 dh.lockUpgradeFsm.RLock()
1484 if dh.pOnuUpradeFsm != nil {
1485 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001486 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001487 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001488 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1489 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001490 }
mpagenko59862f02021-10-11 08:53:18 +00001491 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1492 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1493 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1494 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001495 // use the OnuVendor identification from this device for the internal unique name
1496 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001497 // 1.) check a started upgrade process and relay the commitment request to it
1498 // the running upgrade may be based either on the imageIdentifier (started from download)
1499 // or on the imageVersion (started from pure activation)
1500 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1501 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001502 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001503 "device-id": dh.DeviceID, "error": err})
1504 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001505 }
mpagenko183647c2021-06-08 15:25:04 +00001506 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001507 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001508 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001509 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001510 } //else
1511 dh.lockUpgradeFsm.RUnlock()
1512
mpagenko183647c2021-06-08 15:25:04 +00001513 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001514 var activeImageID uint16
1515 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1516 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001517 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1518 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001519 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001520 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001521 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001522 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001523 if err == nil {
1524 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1525 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001526 "device-id": dh.DeviceID, "error": err})
1527 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001528 }
1529 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001530 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001531 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001532 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001533 } //else
1534 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001535 "device-id": dh.DeviceID, "error": err})
1536 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001537}
1538
mpagenkoaa3afe92021-05-21 16:20:58 +00001539func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001540 aVersion string) *voltha.ImageState {
1541 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001542 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001543 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001544 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001545 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1546 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1547 if aVersion == dh.pLastUpgradeImageState.Version {
1548 pImageState = dh.pLastUpgradeImageState
1549 } else { //state request for an image version different from last processed image version
1550 pImageState = &voltha.ImageState{
1551 Version: aVersion,
1552 //we cannot state something concerning this version
1553 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1554 Reason: voltha.ImageState_NO_ERROR,
1555 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1556 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001557 }
1558 }
mpagenko38662d02021-08-11 09:45:19 +00001559 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001560}
1561
1562func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1563 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001564 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001565 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001566 dh.lockUpgradeFsm.RLock()
1567 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001568 dh.lockUpgradeFsm.RUnlock()
1569 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001570 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001571 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1572 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1573 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1574 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1575 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1576 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001577 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1578 dh.upgradeCanceled = true
1579 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1580 }
mpagenko45586762021-10-01 08:30:22 +00001581 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001582 } else {
mpagenko45586762021-10-01 08:30:22 +00001583 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001584 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1585 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1586 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1587 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1588 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1589 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001590 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1591 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001592 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1593 //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 +00001594 }
1595}
1596
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001597func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1598
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001599 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001600
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001601 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001602 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001603 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1604 pDevEntry.MutexOnuImageStatus.Lock()
1605 pDevEntry.POnuImageStatus = onuImageStatus
1606 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001607
1608 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001609 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001610 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1611 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001612 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1613 pDevEntry.MutexOnuImageStatus.Lock()
1614 pDevEntry.POnuImageStatus = nil
1615 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001616 return images, err
1617}
1618
Himani Chawla6d2ae152020-09-02 13:11:20 +05301619// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001620// #####################################################################################
1621
1622// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301623// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001624
dbainbri4d3a0dc2020-12-02 00:33:42 +00001625func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001626 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1627 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001628}
1629
1630// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001631func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001632
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001633 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001634 var err error
1635
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001636 // populate what we know. rest comes later after mib sync
1637 dh.device.Root = false
1638 dh.device.Vendor = "OpenONU"
1639 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001640 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001641 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001642
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001643 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001644
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001645 if !dh.IsReconciling() {
1646 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001647 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1648 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1649 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301650 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001651 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001652 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001653 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001654 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001655
Himani Chawla4d908332020-08-31 12:30:20 +05301656 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001657 dh.ponPortNumber = dh.device.ParentPortNo
1658
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001659 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1660 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1661 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001662 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001663 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301664 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001665
1666 /*
1667 self._pon = PonPort.create(self, self._pon_port_number)
1668 self._pon.add_peer(self.parent_id, self._pon_port_number)
1669 self.logger.debug('adding-pon-port-to-agent',
1670 type=self._pon.get_port().type,
1671 admin_state=self._pon.get_port().admin_state,
1672 oper_status=self._pon.get_port().oper_status,
1673 )
1674 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001675 if !dh.IsReconciling() {
1676 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001677 var ponPortNo uint32 = 1
1678 if dh.ponPortNumber != 0 {
1679 ponPortNo = dh.ponPortNumber
1680 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001681
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001682 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001683 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001684 PortNo: ponPortNo,
1685 Label: fmt.Sprintf("pon-%d", ponPortNo),
1686 Type: voltha.Port_PON_ONU,
1687 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301688 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001689 PortNo: ponPortNo}}, // Peer port is parent's port number
1690 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001691 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001692 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001693 e.Cancel(err)
1694 return
1695 }
1696 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001697 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001698 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001699 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001700}
1701
1702// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001703func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001704
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001705 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001706 var err error
1707 /*
1708 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1709 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1710 return nil
1711 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001712 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001713 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001714 e.Cancel(err)
1715 return
1716 }
1717
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001718 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001719 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001720 // reconcilement will be continued after mib download is done
1721 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001722
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001723 /*
1724 ############################################################################
1725 # Setup Alarm handler
1726 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1727 device.serial_number)
1728 ############################################################################
1729 # Setup PM configuration for this device
1730 # Pass in ONU specific options
1731 kwargs = {
1732 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1733 'heartbeat': self.heartbeat,
1734 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1735 }
1736 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1737 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1738 self.logical_device_id, device.serial_number,
1739 grouped=True, freq_override=False, **kwargs)
1740 pm_config = self._pm_metrics.make_proto()
1741 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1742 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1743 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1744
1745 # Note, ONU ID and UNI intf set in add_uni_port method
1746 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1747 ani_ports=[self._pon])
1748
1749 # Code to Run OMCI Test Action
1750 kwargs_omci_test_action = {
1751 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1752 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1753 }
1754 serial_number = device.serial_number
1755 self._test_request = OmciTestRequest(self.core_proxy,
1756 self.omci_agent, self.device_id,
1757 AniG, serial_number,
1758 self.logical_device_id,
1759 exclusive=False,
1760 **kwargs_omci_test_action)
1761
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001762 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001763 else:
1764 self.logger.info('onu-already-activated')
1765 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001766
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001767 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001768}
1769
1770// doStateConnected get the device info and update to voltha core
1771// for comparison of the original method (not that easy to uncomment): compare here:
1772// voltha-openolt-adapter/adaptercore/device_handler.go
1773// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001774func (dh *deviceHandler) doStateConnected(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, "doStateConnected-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, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001780}
1781
1782// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001783func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001784
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001785 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301786 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001787 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001788 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001789
1790 /*
1791 // Synchronous call to update device state - this method is run in its own go routine
1792 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1793 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001794 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 +00001795 return err
1796 }
1797 return nil
1798 */
1799}
1800
1801// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001802func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001803
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001804 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001805 var err error
1806
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001807 device := dh.device
1808 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001809 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001810 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001811 e.Cancel(err)
1812 return
1813 }
1814
1815 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001816 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001817 /*
1818 // Update the all ports state on that device to disable
1819 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001820 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001821 return er
1822 }
1823
1824 //Update the device oper state and connection status
1825 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1826 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1827 dh.device = cloned
1828
1829 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001830 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001831 return er
1832 }
1833
1834 //get the child device for the parent device
1835 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1836 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001837 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001838 return err
1839 }
1840 for _, onuDevice := range onuDevices.Items {
1841
1842 // Update onu state as down in onu adapter
1843 onuInd := oop.OnuIndication{}
1844 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001845 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001846 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1847 if er != nil {
1848 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001849 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001850 //Do not return here and continue to process other ONUs
1851 }
1852 }
1853 // * Discovered ONUs entries need to be cleared , since after OLT
1854 // is up, it starts sending discovery indications again* /
1855 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001856 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001857 return nil
1858 */
Himani Chawla4d908332020-08-31 12:30:20 +05301859 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001860 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001861 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001862}
1863
Himani Chawla6d2ae152020-09-02 13:11:20 +05301864// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001865// #################################################################################
1866
1867// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301868// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001869
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001870//GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
1871func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001872 dh.lockDevice.RLock()
1873 pOnuDeviceEntry := dh.pOnuOmciDevice
1874 if aWait && pOnuDeviceEntry == nil {
1875 //keep the read sema short to allow for subsequent write
1876 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001877 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001878 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1879 // so it might be needed to wait here for that event with some timeout
1880 select {
1881 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001882 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001883 return nil
1884 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001885 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001886 // if written now, we can return the written value without sema
1887 return dh.pOnuOmciDevice
1888 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001889 }
mpagenko3af1f032020-06-10 08:53:41 +00001890 dh.lockDevice.RUnlock()
1891 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001892}
1893
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001894//setDeviceHandlerEntries sets the ONU device entry within the handler
1895func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1896 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001897 dh.lockDevice.Lock()
1898 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001899 dh.pOnuOmciDevice = apDeviceEntry
1900 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001901 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301902 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001903 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001904}
1905
Himani Chawla6d2ae152020-09-02 13:11:20 +05301906//addOnuDeviceEntry creates a new ONU device or returns the existing
1907func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001908 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001909
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001910 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001911 if deviceEntry == nil {
1912 /* costum_me_map in python code seems always to be None,
1913 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1914 /* also no 'clock' argument - usage open ...*/
1915 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001916 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1917 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1918 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1919 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1920 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001921 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001922 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001923 // fire deviceEntry ready event to spread to possibly waiting processing
1924 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001925 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001926 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001927 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001928 }
1929 // might be updated with some error handling !!!
1930 return nil
1931}
1932
dbainbri4d3a0dc2020-12-02 00:33:42 +00001933func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001934 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001935 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1936
1937 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001938
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001939 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001940 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001941 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1942 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001943 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001944 if !dh.IsReconciling() {
1945 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001946 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001947 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001948 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001949 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001950 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001951
khenaidoo42dcdfd2021-10-19 17:34:12 -04001952 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001953 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001954 OperStatus: voltha.OperStatus_ACTIVATING,
1955 ConnStatus: voltha.ConnectStatus_REACHABLE,
1956 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001957 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001958 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001959 }
1960 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001961 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001962 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001963
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001964 pDevEntry.MutexPersOnuConfig.RLock()
1965 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1966 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001967 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 +00001968 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001969 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001970 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001971 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001972 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001973 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001974 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1975 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1976 // 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 +00001977 // 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 +00001978 // so let's just try to keep it simple ...
1979 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001980 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001981 if err != nil || device == nil {
1982 //TODO: needs to handle error scenarios
1983 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1984 return errors.New("Voltha Device not found")
1985 }
1986 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001987
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001988 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001989 return err
mpagenko3af1f032020-06-10 08:53:41 +00001990 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001991 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001992
1993 /* this might be a good time for Omci Verify message? */
1994 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001995 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001996 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001997 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001998 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001999
2000 /* give the handler some time here to wait for the OMCi verification result
2001 after Timeout start and try MibUpload FSM anyway
2002 (to prevent stopping on just not supported OMCI verification from ONU) */
2003 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002004 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002005 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002006 case testresult := <-verifyExec:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002007 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002008 }
2009
2010 /* In py code it looks earlier (on activate ..)
2011 # Code to Run OMCI Test Action
2012 kwargs_omci_test_action = {
2013 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2014 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2015 }
2016 serial_number = device.serial_number
2017 self._test_request = OmciTestRequest(self.core_proxy,
2018 self.omci_agent, self.device_id,
2019 AniG, serial_number,
2020 self.logical_device_id,
2021 exclusive=False,
2022 **kwargs_omci_test_action)
2023 ...
2024 # Start test requests after a brief pause
2025 if not self._test_request_started:
2026 self._test_request_started = True
2027 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2028 reactor.callLater(tststart, self._test_request.start_collector)
2029
2030 */
2031 /* which is then: in omci_test_request.py : */
2032 /*
2033 def start_collector(self, callback=None):
2034 """
2035 Start the collection loop for an adapter if the frequency > 0
2036
2037 :param callback: (callable) Function to call to collect PM data
2038 """
2039 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2040 if callback is None:
2041 callback = self.perform_test_omci
2042
2043 if self.lc is None:
2044 self.lc = LoopingCall(callback)
2045
2046 if self.default_freq > 0:
2047 self.lc.start(interval=self.default_freq / 10)
2048
2049 def perform_test_omci(self):
2050 """
2051 Perform the initial test request
2052 """
2053 ani_g_entities = self._device.configuration.ani_g_entities
2054 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2055 is not None else None
2056 self._entity_id = ani_g_entities_ids[0]
2057 self.logger.info('perform-test', entity_class=self._entity_class,
2058 entity_id=self._entity_id)
2059 try:
2060 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2061 result = yield self._device.omci_cc.send(frame)
2062 if not result.fields['omci_message'].fields['success_code']:
2063 self.logger.info('Self-Test Submitted Successfully',
2064 code=result.fields[
2065 'omci_message'].fields['success_code'])
2066 else:
2067 raise TestFailure('Test Failure: {}'.format(
2068 result.fields['omci_message'].fields['success_code']))
2069 except TimeoutError as e:
2070 self.deferred.errback(failure.Failure(e))
2071
2072 except Exception as e:
2073 self.logger.exception('perform-test-Error', e=e,
2074 class_id=self._entity_class,
2075 entity_id=self._entity_id)
2076 self.deferred.errback(failure.Failure(e))
2077
2078 */
2079
2080 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002081 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002082
mpagenko1cc3cb42020-07-27 15:24:38 +00002083 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2084 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2085 * 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 +05302086 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002087 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002088 //call MibUploadFSM - transition up to state UlStInSync
2089 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002090 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002091 if pMibUlFsm.Is(mib.UlStDisabled) {
2092 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2093 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2094 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302095 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002096 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302097 //Determine ONU status and start/re-start MIB Synchronization tasks
2098 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002099 if pDevEntry.IsNewOnu() {
2100 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2101 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2102 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002103 }
Himani Chawla4d908332020-08-31 12:30:20 +05302104 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002105 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2106 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2107 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302108 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002109 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002110 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002111 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002112 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002113 "device-id": dh.DeviceID})
2114 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002115 }
2116 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002117 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2118 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002119 }
2120 return nil
2121}
2122
dbainbri4d3a0dc2020-12-02 00:33:42 +00002123func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00002124 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002125 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002126 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
2127 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002128
mpagenko900ee4b2020-10-12 11:56:34 +00002129 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2130 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2131 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002132 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002133 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002134 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002135 // abort: system behavior is just unstable ...
2136 return err
2137 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002138 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002139 _ = 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 +00002140
2141 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002142 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002143 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002144 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002145 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2146 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002147 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002148 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002149
2150 //TODO!!! remove existing traffic profiles
2151 /* from py code, if TP's exist, remove them - not yet implemented
2152 self._tp = dict()
2153 # Let TP download happen again
2154 for uni_id in self._tp_service_specific_task:
2155 self._tp_service_specific_task[uni_id].clear()
2156 for uni_id in self._tech_profile_download_done:
2157 self._tech_profile_download_done[uni_id].clear()
2158 */
2159
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002160 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002161
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002162 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002163
mpagenkoe4782082021-11-25 12:04:26 +00002164 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002165 // abort: system behavior is just unstable ...
2166 return err
2167 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002168 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002169 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002170 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002171 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002172 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2173 OperStatus: voltha.OperStatus_DISCOVERED,
2174 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002175 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002176 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002177 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002178 // abort: system behavior is just unstable ...
2179 return err
2180 }
2181 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002182 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002183 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002184 return nil
2185}
2186
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002187func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002188 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2189 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2190 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2191 // and using the stop/reset event should never harm
2192
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002193 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002194 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002195 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2196 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00002197 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002198 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002199 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002200 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002201 pDevEntry.MutexOnuImageStatus.RLock()
2202 if pDevEntry.POnuImageStatus != nil {
2203 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002204 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002205 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002206
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002207 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002208 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002209 }
2210 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002211 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002212 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002213 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002214 }
mpagenko101ac942021-11-16 15:01:29 +00002215 //stop any deviceHandler reconcile processing (if running)
2216 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002217 //port lock/unlock FSM's may be active
2218 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002219 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002220 }
2221 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002222 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002223 }
2224 //techProfile related PonAniConfigFsm FSM may be active
2225 if dh.pOnuTP != nil {
2226 // should always be the case here
2227 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002228 if dh.pOnuTP.PAniConfigFsm != nil {
2229 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2230 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002231 }
mpagenko900ee4b2020-10-12 11:56:34 +00002232 }
2233 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002234 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002235 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002236 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002237 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002238 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002239 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002240 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002241 } else {
2242 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002243 }
2244 }
2245 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002246 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002247 // Stop collector routine
2248 dh.stopCollector <- true
2249 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002250 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302251 dh.stopAlarmManager <- true
2252 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002253 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002254 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002255 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302256
Girish Gowdrae95687a2021-09-08 16:30:58 -07002257 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2258
mpagenko80622a52021-02-09 16:53:23 +00002259 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002260 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002261 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002262 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002263 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002264 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002265 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002266 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2267 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2268 // (even though it may also run into direct cancellation, a bit hard to verify here)
2269 // so don't set 'dh.upgradeCanceled = true' here!
2270 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2271 }
mpagenko38662d02021-08-11 09:45:19 +00002272 }
mpagenko80622a52021-02-09 16:53:23 +00002273
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002274 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002275 return nil
2276}
2277
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002278func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2279 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 +05302280
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002281 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002282 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002283 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002284 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002285 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002286 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002287 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002288
mpagenkoa40e99a2020-11-17 13:50:39 +00002289 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2290 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2291 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2292 * disable/enable toggling here to allow traffic
2293 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2294 * like the py comment says:
2295 * # start by locking all the unis till mib sync and initial mib is downloaded
2296 * # this way we can capture the port down/up events when we are ready
2297 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302298
mpagenkoa40e99a2020-11-17 13:50:39 +00002299 // Init Uni Ports to Admin locked state
2300 // *** should generate UniLockStateDone event *****
2301 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002302 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002303 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002304 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002305 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002306 }
2307}
2308
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002309func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2310 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302311 /* Mib download procedure -
2312 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2313 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002314 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002315 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002316 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002317 return
2318 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002319 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302320 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002321 if pMibDlFsm.Is(mib.DlStDisabled) {
2322 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2323 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 +05302324 // maybe try a FSM reset and then again ... - TODO!!!
2325 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002326 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302327 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002328 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2329 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302330 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002331 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302332 //Begin MIB data download (running autonomously)
2333 }
2334 }
2335 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002336 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002337 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302338 // maybe try a FSM reset and then again ... - TODO!!!
2339 }
2340 /***** Mib download started */
2341 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002342 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302343 }
2344}
2345
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002346func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2347 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302348 //initiate DevStateUpdate
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002349 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002350 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002351 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002352 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2353 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2354 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2355 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002356 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002357 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002358 ConnStatus: voltha.ConnectStatus_REACHABLE,
2359 OperStatus: voltha.OperStatus_ACTIVE,
2360 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302361 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002362 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302363 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002364 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302365 }
2366 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002367 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002368 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302369 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002370 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002371
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002372 if !dh.GetCollectorIsRunning() {
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002373 // Start PM collector routine
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002374 go dh.StartCollector(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002375 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002376 if !dh.GetAlarmManagerIsRunning(ctx) {
2377 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002378 }
2379
Girish Gowdrae95687a2021-09-08 16:30:58 -07002380 // Start flow handler routines per UNI
2381 for _, uniPort := range dh.uniEntityMap {
2382 // only if this port was enabled for use by the operator at startup
2383 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2384 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2385 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2386 }
2387 }
2388 }
2389
Girish Gowdrae0140f02021-02-02 16:55:09 -08002390 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002391 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002392 // There is no way we should be landing here, but if we do then
2393 // there is nothing much we can do about this other than log error
2394 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2395 }
2396
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002397 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002398
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002399 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002400 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002401 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002402 return
2403 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002404 pDevEntry.MutexPersOnuConfig.RLock()
2405 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2406 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002407 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002408 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002409 dh.mutexForDisableDeviceRequested.Lock()
2410 dh.disableDeviceRequested = true
2411 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002412 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002413 // reconcilement will be continued after ani config is done
2414 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002415 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002416 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002417 dh.mutexForDisableDeviceRequested.RLock()
2418 if !dh.disableDeviceRequested {
2419 if dh.pUnlockStateFsm == nil {
2420 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2421 } else { //UnlockStateFSM already init
2422 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2423 dh.runUniLockFsm(ctx, false)
2424 }
2425 dh.mutexForDisableDeviceRequested.RUnlock()
2426 } else {
2427 dh.mutexForDisableDeviceRequested.RUnlock()
2428 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002429 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302430 }
2431}
2432
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002433func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2434 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302435
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002436 if !dh.IsReconciling() {
2437 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002438 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002439 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2440 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002441 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002442 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002443 return
2444 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002445 pDevEntry.MutexPersOnuConfig.Lock()
2446 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2447 pDevEntry.MutexPersOnuConfig.Unlock()
2448 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002449 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002450 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002451 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302452 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002453 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 +00002454 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002455 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002456 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302457 }
2458}
2459
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002460func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002461 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002462 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002463
mpagenko44bd8362021-11-15 11:40:05 +00002464 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002465 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002466 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002467 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002468 OperStatus: voltha.OperStatus_UNKNOWN,
2469 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002470 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002471 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002472 }
2473
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002474 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002475 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002476 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002477
2478 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002479 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002480
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002481 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002482 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002483 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002484 return
2485 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002486 pDevEntry.MutexPersOnuConfig.Lock()
2487 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2488 pDevEntry.MutexPersOnuConfig.Unlock()
2489 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002490 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002491 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002492 }
mpagenko900ee4b2020-10-12 11:56:34 +00002493}
2494
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002495func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002496 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002497 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002498 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002499 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002500 ConnStatus: voltha.ConnectStatus_REACHABLE,
2501 OperStatus: voltha.OperStatus_ACTIVE,
2502 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002503 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002504 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002505 }
2506
dbainbri4d3a0dc2020-12-02 00:33:42 +00002507 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002508 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002509 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002510 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002511
2512 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002513 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002514
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002515 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002516 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002517 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002518 return
2519 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002520 pDevEntry.MutexPersOnuConfig.Lock()
2521 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2522 pDevEntry.MutexPersOnuConfig.Unlock()
2523 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002524 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002525 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002526 }
mpagenko900ee4b2020-10-12 11:56:34 +00002527}
2528
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002529func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2530 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2531 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002532 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002533 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002534 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002535 OperStatus: voltha.OperStatus_FAILED,
2536 }); err != nil {
2537 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2538 }
2539}
2540
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002541func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2542 if devEvent == cmn.OmciAniConfigDone {
2543 logger.Debugw(ctx, "OmciAniConfigDone 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.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002547 // 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 +00002548 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302549 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002550 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002551 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
2552 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
2553 dh.mutexReconcilingFirstPassFlag.Lock()
2554 if dh.reconcilingFirstPass {
2555 logger.Debugw(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
2556 dh.reconcilingFirstPass = false
2557 go dh.ReconcileDeviceFlowConfig(ctx)
2558 }
2559 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00002560 }
2561 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002562 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002563 // attention: the device reason update is done based on ONU-UNI-Port related activity
2564 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002565 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002566 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
2567 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002568 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002569 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302570}
2571
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002572func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002573 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002574 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302575 // attention: the device reason update is done based on ONU-UNI-Port related activity
2576 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302577
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002578 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2579 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00002580 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00002581 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002582 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00002583 }
2584 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002585 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002586 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00002587 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002588 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302589 }
mpagenkof1fc3862021-02-16 10:09:52 +00002590
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002591 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002592 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002593 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002594 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002595 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002596 }
2597 } else {
2598 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002599 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002600 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302601}
2602
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002603//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
2604func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302605 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002606 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002607 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002608 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002609 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002610 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002611 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002612 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002613 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002614 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002615 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002616 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002617 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002618 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002619 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002620 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002621 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002622 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002623 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002624 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002625 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002626 case cmn.UniEnableStateFailed:
2627 {
2628 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2629 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002630 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002631 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002632 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002633 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002634 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002635 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002636 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002637 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002638 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002639 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002640 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002641 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002642 default:
2643 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002644 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002645 }
2646 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002647}
2648
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002649func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002650 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002651 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302652 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002653 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002654 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002655 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302656 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002657 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002658 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002659 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 +00002660 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002661 //store UniPort with the System-PortNumber key
2662 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002663 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002664 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002665 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002666 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002667 } //error logging already within UniPort method
2668 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002669 logger.Debugw(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002670 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002671 }
2672 }
2673}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002674
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002675func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2676 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002677 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002678 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002679 return
2680 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002681 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002682 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002683 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2684 for _, mgmtEntityID := range pptpInstKeys {
2685 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002686 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002687 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2688 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002689 }
2690 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002691 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002692 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002693 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002694 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2695 for _, mgmtEntityID := range veipInstKeys {
2696 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002697 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002698 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2699 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002700 }
2701 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002702 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002703 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002704 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002705 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2706 for _, mgmtEntityID := range potsInstKeys {
2707 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002708 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002709 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2710 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002711 }
2712 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002713 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002714 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002715 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002716 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002717 return
2718 }
2719
mpagenko2c3f6c52021-11-23 11:22:10 +00002720 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
2721 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
2722 // 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 -07002723 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2724 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2725 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00002726 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
2727 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002728 for i := 0; i < int(uniCnt); i++ {
2729 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
2730 dh.stopFlowMonitoringRoutine[i] = make(chan bool)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002731 }
2732}
2733
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002734// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2735func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002736 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302737 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002738 // with following remark:
2739 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2740 // # load on the core
2741
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002742 // 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 +00002743
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002744 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002745 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002746 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2747 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2748 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2749 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002750 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002751 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002752 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002753 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002754 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002755 PortNo: port.PortNo,
2756 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002757 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002758 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 -04002759 }
2760 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002761 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002762 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002763 }
mpagenko3af1f032020-06-10 08:53:41 +00002764 }
2765 }
2766}
2767
2768// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002769func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2770 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002771 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2772 for uniNo, uniPort := range dh.uniEntityMap {
2773 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002774
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002775 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2776 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2777 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2778 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002779 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002780 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002781 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002782 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002783 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002784 PortNo: port.PortNo,
2785 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002786 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002787 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 -04002788 }
2789 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002790 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002791 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002792 }
2793
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002794 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002795 }
2796}
2797
2798// ONU_Active/Inactive announcement on system KAFKA bus
2799// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002800func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002801 var de voltha.DeviceEvent
2802 eventContext := make(map[string]string)
2803 //Populating event context
2804 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002805 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002806 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002807 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002808 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002809 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 +00002810 }
2811 oltSerialNumber := parentDevice.SerialNumber
2812
2813 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2814 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2815 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302816 eventContext["olt-serial-number"] = oltSerialNumber
2817 eventContext["device-id"] = aDeviceID
2818 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002819 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002820 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2821 deviceEntry.MutexPersOnuConfig.RLock()
2822 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2823 deviceEntry.MutexPersOnuConfig.RUnlock()
2824 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
2825 deviceEntry.MutexPersOnuConfig.RLock()
2826 eventContext["vendor"] = deviceEntry.SOnuPersistentData.PersVendorID
2827 deviceEntry.MutexPersOnuConfig.RUnlock()
2828 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002829 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2830 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2831 } else {
2832 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2833 log.Fields{"device-id": aDeviceID})
2834 return
2835 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002836
2837 /* Populating device event body */
2838 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302839 de.ResourceId = aDeviceID
2840 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002841 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2842 de.Description = fmt.Sprintf("%s Event - %s - %s",
2843 cEventObjectType, cOnuActivatedEvent, "Raised")
2844 } else {
2845 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2846 de.Description = fmt.Sprintf("%s Event - %s - %s",
2847 cEventObjectType, cOnuActivatedEvent, "Cleared")
2848 }
2849 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002850 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2851 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302852 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002853 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002854 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302855 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002856}
2857
Himani Chawla4d908332020-08-31 12:30:20 +05302858// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002859func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2860 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002861 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302862 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002863 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002864 sFsmName = "LockStateFSM"
2865 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002866 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002867 sFsmName = "UnLockStateFSM"
2868 }
mpagenko3af1f032020-06-10 08:53:41 +00002869
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002870 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002871 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002872 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002873 return
2874 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002875 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002876 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302877 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002878 dh.pLockStateFsm = pLSFsm
2879 } else {
2880 dh.pUnlockStateFsm = pLSFsm
2881 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002882 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002883 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002884 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002885 }
2886}
2887
2888// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002889func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002890 /* Uni Port lock/unlock procedure -
2891 ***** should run via 'adminDone' state and generate the argument requested event *****
2892 */
2893 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302894 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002895 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002896 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2897 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002898 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2899 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002900 }
2901 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002902 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002903 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2904 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002905 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2906 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002907 }
2908 }
2909 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002910 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2911 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002912 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002913 // maybe try a FSM reset and then again ... - TODO!!!
2914 } else {
2915 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002916 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002917 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002918 }
2919 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002920 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002921 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002922 // maybe try a FSM reset and then again ... - TODO!!!
2923 }
2924 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002925 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002926 // maybe try a FSM reset and then again ... - TODO!!!
2927 }
2928}
2929
mpagenko80622a52021-02-09 16:53:23 +00002930// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00002931// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002932func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002933 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002934 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002935 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002936 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002937 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002938 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002939 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002940 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002941 sFsmName, chUpgradeFsm)
2942 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002943 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00002944 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002945 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
2946 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002947 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00002948 // maybe try a FSM reset and then again ... - TODO!!!
2949 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2950 }
mpagenko59862f02021-10-11 08:53:18 +00002951 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00002952 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2953 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00002954 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2955 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002956 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002957 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002958 } else {
2959 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002960 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002961 // maybe try a FSM reset and then again ... - TODO!!!
2962 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2963 }
2964 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002965 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002966 // maybe try a FSM reset and then again ... - TODO!!!
2967 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2968 }
2969 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002970 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002971 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2972 }
2973 return nil
2974}
2975
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002976// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
2977func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002978 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002979 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002980 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00002981 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2982 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00002983 dh.pLastUpgradeImageState = apImageState
2984 dh.lockUpgradeFsm.Unlock()
2985 //signal upgradeFsm removed using non-blocking channel send
2986 select {
2987 case dh.upgradeFsmChan <- struct{}{}:
2988 default:
2989 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002990 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00002991 }
mpagenko80622a52021-02-09 16:53:23 +00002992}
2993
mpagenko15ff4a52021-03-02 10:09:20 +00002994// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2995func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002996 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00002997 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002998 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002999 return
3000 }
3001
3002 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003003 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003004 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003005 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3006 dh.lockUpgradeFsm.RUnlock()
3007 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3008 return
3009 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003010 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003011 if pUpgradeStatemachine != nil {
3012 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3013 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003014 UpgradeState := pUpgradeStatemachine.Current()
3015 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3016 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3017 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003018 // 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 +00003019 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003020 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3021 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003022 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003023 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003024 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003025 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3026 dh.upgradeCanceled = true
3027 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3028 }
mpagenko15ff4a52021-03-02 10:09:20 +00003029 return
3030 }
mpagenko59862f02021-10-11 08:53:18 +00003031 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003032 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3033 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003034 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003035 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003036 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3037 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003038 return
3039 }
3040 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003041 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003042 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003043 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3044 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003045 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3046 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003047 return
3048 }
3049 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003050 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003051 }
3052 } else {
3053 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 +00003054 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003055 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3056 dh.upgradeCanceled = true
3057 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3058 }
mpagenko1f8e8822021-06-25 14:10:21 +00003059 }
mpagenko15ff4a52021-03-02 10:09:20 +00003060 return
3061 }
mpagenko59862f02021-10-11 08:53:18 +00003062 dh.lockUpgradeFsm.RUnlock()
3063 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3064 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003065 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3066 dh.upgradeCanceled = true
3067 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3068 }
mpagenko59862f02021-10-11 08:53:18 +00003069 return
3070 }
3071 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3072 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3073 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3074 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3075 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3076 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3077 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003078 }
mpagenko15ff4a52021-03-02 10:09:20 +00003079 }
3080 }
3081 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003082 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003083 }
mpagenko59862f02021-10-11 08:53:18 +00003084 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003085}
3086
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003087//SetBackend provides a DB backend for the specified path on the existing KV client
3088func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003089
3090 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003091 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003092 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003093 kvbackend := &db.Backend{
3094 Client: dh.pOpenOnuAc.kvClient,
3095 StoreType: dh.pOpenOnuAc.KVStoreType,
3096 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003097 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003098 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3099 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003100
mpagenkoaf801632020-07-03 10:00:42 +00003101 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003102}
khenaidoo7d3c5582021-08-11 18:09:44 -04003103func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05303104 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003105
mpagenkodff5dda2020-08-28 11:52:01 +00003106 for _, field := range flow.GetOfbFields(apFlowItem) {
3107 switch field.Type {
3108 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3109 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003110 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003111 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3112 }
mpagenko01e726e2020-10-23 09:45:29 +00003113 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003114 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3115 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303116 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003117 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303118 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3119 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003120 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3121 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003122 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003123 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303124 return
mpagenkodff5dda2020-08-28 11:52:01 +00003125 }
3126 }
mpagenko01e726e2020-10-23 09:45:29 +00003127 */
mpagenkodff5dda2020-08-28 11:52:01 +00003128 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3129 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303130 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003131 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303132 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003133 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303134 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003135 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003136 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303137 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003138 }
3139 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3140 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303141 *loAddPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003142 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003143 "PCP": loAddPcp})
3144 }
3145 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3146 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003147 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003148 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3149 }
3150 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3151 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003152 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003153 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3154 }
3155 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3156 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003157 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003158 "IPv4-DST": field.GetIpv4Dst()})
3159 }
3160 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3161 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003162 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003163 "IPv4-SRC": field.GetIpv4Src()})
3164 }
3165 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3166 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003167 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003168 "Metadata": field.GetTableMetadata()})
3169 }
3170 /*
3171 default:
3172 {
3173 //all other entires ignored
3174 }
3175 */
3176 }
3177 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303178}
mpagenkodff5dda2020-08-28 11:52:01 +00003179
khenaidoo7d3c5582021-08-11 18:09:44 -04003180func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003181 for _, action := range flow.GetActions(apFlowItem) {
3182 switch action.Type {
3183 /* not used:
3184 case of.OfpActionType_OFPAT_OUTPUT:
3185 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003186 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003187 "Output": action.GetOutput()})
3188 }
3189 */
3190 case of.OfpActionType_OFPAT_PUSH_VLAN:
3191 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003192 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003193 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3194 }
3195 case of.OfpActionType_OFPAT_SET_FIELD:
3196 {
3197 pActionSetField := action.GetSetField()
3198 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003199 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003200 "OxcmClass": pActionSetField.Field.OxmClass})
3201 }
3202 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303203 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003204 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303205 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003206 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303207 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003208 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303209 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003210 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003211 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003212 "Type": pActionSetField.Field.GetOfbField().Type})
3213 }
3214 }
3215 /*
3216 default:
3217 {
3218 //all other entires ignored
3219 }
3220 */
3221 }
3222 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303223}
3224
3225//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003226func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003227 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303228 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3229 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
3230 var loAddPcp, loSetPcp uint8
3231 var loIPProto uint32
3232 /* the TechProfileId is part of the flow Metadata - compare also comment within
3233 * OLT-Adapter:openolt_flowmgr.go
3234 * Metadata 8 bytes:
3235 * Most Significant 2 Bytes = Inner VLAN
3236 * Next 2 Bytes = Tech Profile ID(TPID)
3237 * Least Significant 4 Bytes = Port ID
3238 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3239 * subscriber related flows.
3240 */
3241
dbainbri4d3a0dc2020-12-02 00:33:42 +00003242 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303243 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003244 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003245 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003246 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303247 }
mpagenko551a4d42020-12-08 18:09:20 +00003248 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003249 loCookie := apFlowItem.GetCookie()
3250 loCookieSlice := []uint64{loCookie}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003251 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003252 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05303253
dbainbri4d3a0dc2020-12-02 00:33:42 +00003254 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003255 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303256 if loIPProto == 2 {
3257 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3258 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003259 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003260 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303261 return nil
3262 }
mpagenko01e726e2020-10-23 09:45:29 +00003263 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003264 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003265
3266 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003267 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003268 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003269 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3270 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3271 //TODO!!: Use DeviceId within the error response to rwCore
3272 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003273 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003274 }
3275 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003276 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003277 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3278 } else {
3279 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3280 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3281 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303282 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003283 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003284 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003285 }
mpagenko9a304ea2020-12-16 15:54:01 +00003286
khenaidoo42dcdfd2021-10-19 17:34:12 -04003287 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003288 if apFlowMetaData != nil {
3289 meter = apFlowMetaData.Meters[0]
3290 }
mpagenkobc4170a2021-08-17 16:42:10 +00003291 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3292 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3293 // when different rules are requested concurrently for the same uni
3294 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3295 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3296 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003297 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3298 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003299 //SetUniFlowParams() may block on some rule that is suspended-to-add
3300 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003301 // Also the error is returned to caller via response channel
3302 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
3303 loMatchVlan, loSetVlan, loSetPcp, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003304 dh.lockVlanConfig.RUnlock()
3305 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003306 return
mpagenkodff5dda2020-08-28 11:52:01 +00003307 }
mpagenkobc4170a2021-08-17 16:42:10 +00003308 dh.lockVlanConfig.RUnlock()
3309 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003310 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003311 loMatchVlan, loSetVlan, loSetPcp, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003312 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003313 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003314 if err != nil {
3315 *respChan <- err
3316 }
mpagenko01e726e2020-10-23 09:45:29 +00003317}
3318
3319//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003320func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003321 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3322 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3323 //no extra check is done on the rule parameters
3324 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3325 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3326 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3327 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003328 // - 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 +00003329 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003330 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003331
3332 /* TT related temporary workaround - should not be needed anymore
3333 for _, field := range flow.GetOfbFields(apFlowItem) {
3334 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3335 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003336 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003337 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3338 if loIPProto == 2 {
3339 // 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 +00003340 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003341 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003342 return nil
3343 }
3344 }
3345 } //for all OfbFields
3346 */
3347
mpagenko9a304ea2020-12-16 15:54:01 +00003348 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003349 dh.lockVlanConfig.RLock()
3350 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003351 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3352 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003353 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3354 return
mpagenko01e726e2020-10-23 09:45:29 +00003355 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003356 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003357 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003358 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003359 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003360 // Push response on the response channel
3361 if respChan != nil {
3362 // 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
3363 select {
3364 case *respChan <- nil:
3365 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3366 default:
3367 }
3368 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003369 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003370}
3371
Himani Chawla26e555c2020-08-31 12:30:20 +05303372// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003373// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003374// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003375func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003376 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 +00003377 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003378
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003379 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003380 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003381 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3382 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003383 }
3384
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003385 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3386 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003387 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003388 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003389 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3390 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003391 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3392 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003393 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003394 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3395 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003396 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3397 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003398 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003399 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303400 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003401 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003402 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3403 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003404 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003405 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003406 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3407 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003408 }
3409 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003410 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003411 "device-id": dh.DeviceID})
3412 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003413 }
3414 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003415 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003416 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3417 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003418 }
3419 return nil
3420}
3421
mpagenkofc4f56e2020-11-04 17:17:49 +00003422//VerifyVlanConfigRequest checks on existence of a given uniPort
3423// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003424func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003425 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003426 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003427 for _, uniPort := range dh.uniEntityMap {
3428 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003429 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003430 pCurrentUniPort = uniPort
3431 break //found - end search loop
3432 }
3433 }
3434 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003435 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003436 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003437 return
3438 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003439 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003440}
3441
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003442//VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
3443func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003444 //TODO!! verify and start pending flow configuration
3445 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3446 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003447
3448 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003449 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003450 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003451 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003452 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003453 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003454 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003455 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003456 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3457 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003458 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003459 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003460 } else {
3461 /***** UniVlanConfigFsm continued */
3462 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003463 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3464 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003465 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003466 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3467 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003468 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003469 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003470 } else {
3471 /***** UniVlanConfigFsm continued */
3472 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003473 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3474 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003475 }
mpagenkodff5dda2020-08-28 11:52:01 +00003476 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003477 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003478 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3479 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003480 }
3481 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003482 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 +00003483 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3484 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003485 }
3486 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003487 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003488 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003489 }
mpagenkof1fc3862021-02-16 10:09:52 +00003490 } else {
3491 dh.lockVlanConfig.RUnlock()
3492 }
mpagenkodff5dda2020-08-28 11:52:01 +00003493}
3494
3495//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3496// 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 +00003497func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003498 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003499 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003500 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003501 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003502 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003503 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003504}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003505
mpagenkof1fc3862021-02-16 10:09:52 +00003506//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003507func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003508 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3509 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3510 // obviously then parallel processing on the cancel must be avoided
3511 // deadline context to ensure completion of background routines waited for
3512 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3513 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3514 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3515
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003516 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003517 var wg sync.WaitGroup
3518 wg.Add(1) // for the 1 go routine to finish
3519
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003520 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003521 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3522
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003523 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003524}
3525
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003526//StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003527//available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003528func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3529 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003530
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003531 if dh.IsReconciling() {
3532 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003533 return nil
3534 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003535 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003536
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003537 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003538 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003539 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3540 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003541 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003542 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003543
mpagenkof1fc3862021-02-16 10:09:52 +00003544 if aWriteToKvStore {
3545 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3546 }
3547 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003548}
3549
dbainbri4d3a0dc2020-12-02 00:33:42 +00003550func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003551 defer cancel() //ensure termination of context (may be pro forma)
3552 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003553 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003554 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003555}
3556
mpagenkoe4782082021-11-25 12:04:26 +00003557//ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
3558// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
3559func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
3560 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
3561 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
3562 dh.mutexDeviceReason.Lock()
3563 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003564 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003565 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003566 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003567 DeviceId: dh.DeviceID,
3568 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003569 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00003570 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003571 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003572 return err
3573 }
mpagenkoe4782082021-11-25 12:04:26 +00003574 } else {
3575 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 +00003576 }
mpagenkoe4782082021-11-25 12:04:26 +00003577 dh.deviceReason = deviceReason
3578 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
3579 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003580 return nil
3581}
3582
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003583func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3584 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003585 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003586 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3587 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003588 }
mpagenkof1fc3862021-02-16 10:09:52 +00003589 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003590}
3591
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003592// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003593// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003594func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3595 dh.lockDevice.RLock()
3596 defer dh.lockDevice.RUnlock()
3597 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003598 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003599 }
3600 return 0, errors.New("error-fetching-uni-port")
3601}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003602
3603// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003604func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3605 var errorsList []error
3606 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 -08003607
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003608 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3609 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3610 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3611
3612 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3613 // successfully.
3614 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3615 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3616 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003617 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 -08003618 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003619 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003620 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003621 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003622}
3623
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003624func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3625 var err error
3626 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003627 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003628
3629 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003630 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003631 errorsList = append(errorsList, err)
3632 }
3633 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003634 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003635
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003636 return errorsList
3637}
3638
3639func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3640 var err error
3641 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003642 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003643 // Check if group metric related config is updated
3644 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003645 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3646 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3647 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003648
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003649 if ok && m.Frequency != v.GroupFreq {
3650 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003651 errorsList = append(errorsList, err)
3652 }
3653 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003654 if ok && m.Enabled != v.Enabled {
3655 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003656 errorsList = append(errorsList, err)
3657 }
3658 }
3659 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003660 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003661 return errorsList
3662}
3663
3664func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3665 var err error
3666 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003667 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003668 // Check if standalone metric related config is updated
3669 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003670 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3671 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3672 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003673
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003674 if ok && m.Frequency != v.SampleFreq {
3675 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003676 errorsList = append(errorsList, err)
3677 }
3678 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003679 if ok && m.Enabled != v.Enabled {
3680 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003681 errorsList = append(errorsList, err)
3682 }
3683 }
3684 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003685 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003686 return errorsList
3687}
3688
3689// nolint: gocyclo
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003690func (dh *deviceHandler) StartCollector(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003691 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08003692
3693 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003694 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303695 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003696 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003697 // Initialize the next metric collection time.
3698 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3699 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003700 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003701 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003702 for {
3703 select {
3704 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003705 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003706 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003707 // Stop the L2 PM FSM
3708 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003709 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3710 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3711 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003712 }
3713 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003714 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003715 }
3716 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003717 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3718 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003719 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003720 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3721 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003722 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003723
Girish Gowdrae09a6202021-01-12 18:10:59 -08003724 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003725 case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3726 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3727 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3728 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3729 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003730 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003731 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003732 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003733 } else {
3734 if dh.pmConfigs.Grouped { // metrics are managed as a group
3735 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003736 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003737
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003738 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3739 // 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 -08003740 // 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 +00003741 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3742 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003743 }
3744 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003745 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3746 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3747 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3748 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003749 }
3750 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003751 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003752
3753 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003754 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3755 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3756 // 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 -08003757 // 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 +00003758 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3759 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003760 }
3761 }
3762 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003763 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3764 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3765 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3766 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003767 }
3768 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003769 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003770 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003771 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003772 } */
3773 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003774 }
3775 }
3776}
kesavandfdf77632021-01-26 23:40:33 -05003777
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003778func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003779
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003780 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3781 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003782}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003783
Himani Chawla43f95ff2021-06-03 00:24:12 +05303784func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3785 if dh.pOnuMetricsMgr == nil {
3786 return &extension.SingleGetValueResponse{
3787 Response: &extension.GetValueResponse{
3788 Status: extension.GetValueResponse_ERROR,
3789 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3790 },
3791 }
3792 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303793 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303794 return resp
3795}
3796
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003797func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3798 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003799 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003800 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003801 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003802}
3803
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003804func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003805 var pAdapterFsm *cmn.AdapterFsm
3806 //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 +00003807 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003808 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003809 {
mpagenkofbf577d2021-10-12 11:44:33 +00003810 if dh.pOnuOmciDevice != nil {
3811 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3812 } else {
3813 return true //FSM not active - so there is no activity on omci
3814 }
mpagenkof1fc3862021-02-16 10:09:52 +00003815 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003816 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003817 {
mpagenkofbf577d2021-10-12 11:44:33 +00003818 if dh.pOnuOmciDevice != nil {
3819 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3820 } else {
3821 return true //FSM not active - so there is no activity on omci
3822 }
mpagenkof1fc3862021-02-16 10:09:52 +00003823 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003824 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003825 {
mpagenkofbf577d2021-10-12 11:44:33 +00003826 if dh.pLockStateFsm != nil {
3827 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3828 } else {
3829 return true //FSM not active - so there is no activity on omci
3830 }
mpagenkof1fc3862021-02-16 10:09:52 +00003831 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003832 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003833 {
mpagenkofbf577d2021-10-12 11:44:33 +00003834 if dh.pUnlockStateFsm != nil {
3835 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3836 } else {
3837 return true //FSM not active - so there is no activity on omci
3838 }
mpagenkof1fc3862021-02-16 10:09:52 +00003839 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003840 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003841 {
mpagenkofbf577d2021-10-12 11:44:33 +00003842 if dh.pOnuMetricsMgr != nil {
3843 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003844 } else {
3845 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003846 }
3847 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003848 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003849 {
3850 dh.lockUpgradeFsm.RLock()
3851 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003852 if dh.pOnuUpradeFsm != nil {
3853 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3854 } else {
3855 return true //FSM not active - so there is no activity on omci
3856 }
mpagenko80622a52021-02-09 16:53:23 +00003857 }
mpagenkof1fc3862021-02-16 10:09:52 +00003858 default:
3859 {
3860 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003861 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003862 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003863 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003864 }
mpagenkofbf577d2021-10-12 11:44:33 +00003865 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3866 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3867 }
3868 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003869}
3870
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003871func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3872 for _, v := range dh.pOnuTP.PAniConfigFsm {
3873 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003874 return false
3875 }
3876 }
3877 return true
3878}
3879
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003880func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003881 dh.lockVlanConfig.RLock()
3882 defer dh.lockVlanConfig.RUnlock()
3883 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003884 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003885 return false
3886 }
3887 }
3888 return true //FSM not active - so there is no activity on omci
3889}
3890
3891func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3892 dh.lockVlanConfig.RLock()
3893 defer dh.lockVlanConfig.RUnlock()
3894 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003895 if v.PAdaptFsm.PFsm != nil {
3896 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003897 return true //there is at least one VLAN FSM with some active configuration
3898 }
3899 }
3900 }
3901 return false //there is no VLAN FSM with some active configuration
3902}
3903
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003904func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003905 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3906 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3907 return false
3908 }
3909 }
3910 // a further check is done to identify, if at least some data traffic related configuration exists
3911 // 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])
3912 return dh.checkUserServiceExists(ctx)
3913}
3914
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003915func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003916 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3917 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003918 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003919 // TODO: fatal error reset ONU, delete deviceHandler!
3920 return
3921 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003922 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
3923 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003924}
3925
3926func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3927 dh.mutexCollectorFlag.Lock()
3928 dh.collectorIsRunning = flagValue
3929 dh.mutexCollectorFlag.Unlock()
3930}
3931
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003932func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003933 dh.mutexCollectorFlag.RLock()
3934 flagValue := dh.collectorIsRunning
3935 dh.mutexCollectorFlag.RUnlock()
3936 return flagValue
3937}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303938
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303939func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3940 dh.mutextAlarmManagerFlag.Lock()
3941 dh.alarmManagerIsRunning = flagValue
3942 dh.mutextAlarmManagerFlag.Unlock()
3943}
3944
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003945func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303946 dh.mutextAlarmManagerFlag.RLock()
3947 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003948 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303949 dh.mutextAlarmManagerFlag.RUnlock()
3950 return flagValue
3951}
3952
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003953func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003954 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303955
3956 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003957 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303958 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303959 if stop := <-dh.stopAlarmManager; stop {
3960 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303961 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303962 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003963 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
3964 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05303965 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303966 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003967 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
3968 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05303969 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303970 }
3971}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003972
Girish Gowdrae95687a2021-09-08 16:30:58 -07003973func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
3974 dh.mutexFlowMonitoringRoutineFlag.Lock()
3975 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003976 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003977 dh.isFlowMonitoringRoutineActive[uniID] = flag
3978}
3979
3980func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
3981 dh.mutexFlowMonitoringRoutineFlag.RLock()
3982 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
3983 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003984 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003985 return dh.isFlowMonitoringRoutineActive[uniID]
3986}
3987
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003988func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
3989 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003990
Maninder7961d722021-06-16 22:10:28 +05303991 connectStatus := voltha.ConnectStatus_UNREACHABLE
3992 operState := voltha.OperStatus_UNKNOWN
3993
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003994 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003995 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003996 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00003997 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003998 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003999 case success := <-dh.chReconcilingFinished:
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004000 logger.Debugw(ctx, "reconciling finished signal received",
4001 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4002 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4003 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4004 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4005 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4006 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4007 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4008 // However, a later refactoring of the functionality remains unaffected.
4009 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004010 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004011 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304012 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004013 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05304014 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00004015 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004016 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05304017 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004018 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4019 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304020 operState = voltha.OperStatus_ACTIVE
4021 } else {
4022 operState = voltha.OperStatus_ACTIVATING
4023 }
4024 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004025 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4026 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4027 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304028 operState = voltha.OperStatus_DISCOVERED
4029 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004030 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004031 logger.Debugw(ctx, "Core DeviceStateUpdate",
4032 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304033 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004034 logger.Debugw(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004035 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004036 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004037 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004038 ConnStatus: connectStatus,
4039 OperStatus: operState,
4040 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304041 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004042 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304043 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004044 } else {
Maninderb5187552021-03-23 22:23:42 +05304045 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004046 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304047
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004048 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304049 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004050 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004051 } else {
4052 onuDevEntry.MutexPersOnuConfig.RLock()
4053 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4054 connectStatus = voltha.ConnectStatus_REACHABLE
4055 }
4056 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304057 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004058 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004059 }
mpagenko101ac942021-11-16 15:01:29 +00004060 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004061 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004062 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004063 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304064
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004065 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304066 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004067 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004068 } else {
4069 onuDevEntry.MutexPersOnuConfig.RLock()
4070 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4071 connectStatus = voltha.ConnectStatus_REACHABLE
4072 }
4073 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304074 }
4075
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004076 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304077
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004078 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004079 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004080 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004081 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004082 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004083
4084 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4085 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4086 } else {
4087 onuDevEntry.MutexReconciledTpInstances.Lock()
4088 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
4089 onuDevEntry.MutexReconciledTpInstances.Unlock()
4090 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004091 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004092 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004093 dh.mutexReconcilingFlag.Lock()
4094 if skipOnuConfig {
4095 dh.reconciling = cSkipOnuConfigReconciling
4096 } else {
4097 dh.reconciling = cOnuConfigReconciling
4098 }
4099 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004100}
4101
mpagenko101ac942021-11-16 15:01:29 +00004102func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004103 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
4104 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004105 dh.sendChReconcileFinished(success)
4106 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4107 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4108 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004109 } else {
mpagenko101ac942021-11-16 15:01:29 +00004110 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004111 }
4112}
4113
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004114func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004115 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004116 defer dh.mutexReconcilingFlag.RUnlock()
4117 return dh.reconciling != cNoReconciling
4118}
4119
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004120func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004121 dh.mutexReconcilingFlag.RLock()
4122 defer dh.mutexReconcilingFlag.RUnlock()
4123 return dh.reconciling == cSkipOnuConfigReconciling
4124}
4125
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004126func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4127 dh.mutexReconcilingFirstPassFlag.Lock()
4128 dh.reconcilingFirstPass = value
4129 dh.mutexReconcilingFirstPassFlag.Unlock()
4130}
4131
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004132func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4133 dh.mutexReconcilingReasonUpdate.Lock()
4134 dh.reconcilingReasonUpdate = value
4135 dh.mutexReconcilingReasonUpdate.Unlock()
4136}
4137
4138func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4139 dh.mutexReconcilingReasonUpdate.RLock()
4140 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4141 return dh.reconcilingReasonUpdate
4142}
4143
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004144func (dh *deviceHandler) getDeviceReason() uint8 {
4145 dh.mutexDeviceReason.RLock()
4146 value := dh.deviceReason
4147 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004148 return value
4149}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004150
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004151func (dh *deviceHandler) GetDeviceReasonString() string {
4152 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004153}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004154
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004155func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004156 dh.mutexReadyForOmciConfig.Lock()
4157 dh.readyForOmciConfig = flagValue
4158 dh.mutexReadyForOmciConfig.Unlock()
4159}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004160func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004161 dh.mutexReadyForOmciConfig.RLock()
4162 flagValue := dh.readyForOmciConfig
4163 dh.mutexReadyForOmciConfig.RUnlock()
4164 return flagValue
4165}
Maninder7961d722021-06-16 22:10:28 +05304166
4167func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004168 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304169 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004170 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304171 }
4172
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004173 logger.Debugw(ctx, "Core DeviceStateUpdate",
4174 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004175 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004176 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004177 ConnStatus: connectStatus,
4178 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4179 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304180 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004181 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304182 }
4183}
khenaidoo7d3c5582021-08-11 18:09:44 -04004184
4185/*
4186Helper functions to communicate with Core
4187*/
4188
4189func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4190 cClient, err := dh.coreClient.GetCoreServiceClient()
4191 if err != nil || cClient == nil {
4192 return nil, err
4193 }
4194 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4195 defer cancel()
4196 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4197 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4198}
4199
khenaidoo42dcdfd2021-10-19 17:34:12 -04004200func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004201 cClient, err := dh.coreClient.GetCoreServiceClient()
4202 if err != nil || cClient == nil {
4203 return err
4204 }
4205 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4206 defer cancel()
4207 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004208 logger.Debugw(subCtx, "device-updated-in-core",
4209 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004210 return err
4211}
4212
4213func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4214 cClient, err := dh.coreClient.GetCoreServiceClient()
4215 if err != nil || cClient == nil {
4216 return err
4217 }
4218 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4219 defer cancel()
4220 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004221 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4222 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004223 return err
4224}
4225
4226func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4227 cClient, err := dh.coreClient.GetCoreServiceClient()
4228 if err != nil || cClient == nil {
4229 return err
4230 }
4231 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4232 defer cancel()
4233 _, err = cClient.DeviceUpdate(subCtx, device)
4234 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4235 return err
4236}
4237
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004238func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004239 cClient, err := dh.coreClient.GetCoreServiceClient()
4240 if err != nil || cClient == nil {
4241 return err
4242 }
4243 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4244 defer cancel()
4245 _, err = cClient.PortCreated(subCtx, port)
4246 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4247 return err
4248}
4249
khenaidoo42dcdfd2021-10-19 17:34:12 -04004250func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004251 cClient, err := dh.coreClient.GetCoreServiceClient()
4252 if err != nil || cClient == nil {
4253 return err
4254 }
4255 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4256 defer cancel()
4257 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004258 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 -04004259 return err
4260}
4261
khenaidoo42dcdfd2021-10-19 17:34:12 -04004262func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004263 cClient, err := dh.coreClient.GetCoreServiceClient()
4264 if err != nil || cClient == nil {
4265 return err
4266 }
4267 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4268 defer cancel()
4269 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004270 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 -04004271 return err
4272}
4273
4274/*
4275Helper functions to communicate with parent adapter
4276*/
4277
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004278func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4279 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4280
4281 var request = ia.TechProfileInstanceRequestMessage{
4282 DeviceId: dh.DeviceID,
4283 TpInstancePath: aTpPath,
4284 ParentDeviceId: dh.parentID,
4285 ParentPonPort: dh.device.ParentPortNo,
4286 OnuId: dh.device.ProxyAddress.OnuId,
4287 UniId: uint32(aUniID),
4288 }
4289
4290 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004291 if err != nil || pgClient == nil {
4292 return nil, err
4293 }
4294 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4295 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004296 logger.Debugw(subCtx, "get-tech-profile-instance",
4297 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004298 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004299}
4300
Girish Gowdrae95687a2021-09-08 16:30:58 -07004301// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4302// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4303func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4304 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4305 dh.setFlowMonitoringIsRunning(uniID, true)
4306 for {
4307 select {
4308 // block on the channel to receive an incoming flow
4309 // process the flow completely before proceeding to handle the next flow
4310 case flowCb := <-dh.flowCbChan[uniID]:
4311 startTime := time.Now()
4312 logger.Debugw(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
4313 respChan := make(chan error)
4314 if flowCb.addFlow {
4315 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4316 } else {
4317 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4318 }
4319 // Block on response and tunnel it back to the caller
4320 *flowCb.respChan <- <-respChan
4321 logger.Debugw(flowCb.ctx, "serial-flow-processor--end",
4322 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4323 case <-dh.stopFlowMonitoringRoutine[uniID]:
4324 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4325 dh.setFlowMonitoringIsRunning(uniID, false)
4326 return
4327 }
4328 }
4329}
4330
khenaidoo42dcdfd2021-10-19 17:34:12 -04004331func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004332 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4333 if err != nil || pgClient == nil {
4334 return err
4335 }
4336 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4337 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004338 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004339 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4340 if err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004341 logger.Errorw(ctx, "omci-failure",
4342 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
4343 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
khenaidoo7d3c5582021-08-11 18:09:44 -04004344 }
4345 return err
4346}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004347
4348// GetDeviceID - TODO: add comment
4349func (dh *deviceHandler) GetDeviceID() string {
4350 return dh.DeviceID
4351}
4352
4353// GetProxyAddressID - TODO: add comment
4354func (dh *deviceHandler) GetProxyAddressID() string {
4355 return dh.device.ProxyAddress.GetDeviceId()
4356}
4357
4358// GetProxyAddressType - TODO: add comment
4359func (dh *deviceHandler) GetProxyAddressType() string {
4360 return dh.device.ProxyAddress.GetDeviceType()
4361}
4362
4363// GetProxyAddress - TODO: add comment
4364func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4365 return dh.device.ProxyAddress
4366}
4367
4368// GetEventProxy - TODO: add comment
4369func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4370 return dh.EventProxy
4371}
4372
4373// GetOmciTimeout - TODO: add comment
4374func (dh *deviceHandler) GetOmciTimeout() int {
4375 return dh.pOpenOnuAc.omciTimeout
4376}
4377
4378// GetAlarmAuditInterval - TODO: add comment
4379func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4380 return dh.pOpenOnuAc.alarmAuditInterval
4381}
4382
4383// GetDlToOnuTimeout4M - TODO: add comment
4384func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4385 return dh.pOpenOnuAc.dlToOnuTimeout4M
4386}
4387
4388// GetUniEntityMap - TODO: add comment
4389func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4390 return &dh.uniEntityMap
4391}
4392
4393// GetPonPortNumber - TODO: add comment
4394func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4395 return &dh.ponPortNumber
4396}
4397
4398// GetUniVlanConfigFsm - TODO: add comment
4399func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004400 dh.lockVlanConfig.RLock()
4401 value := dh.UniVlanConfigFsmMap[uniID]
4402 dh.lockVlanConfig.RUnlock()
4403 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004404}
4405
4406// GetOnuAlarmManager - TODO: add comment
4407func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4408 return dh.pAlarmMgr
4409}
4410
4411// GetOnuMetricsManager - TODO: add comment
4412func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4413 return dh.pOnuMetricsMgr
4414}
4415
4416// GetOnuTP - TODO: add comment
4417func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4418 return dh.pOnuTP
4419}
4420
4421// GetBackendPathPrefix - TODO: add comment
4422func (dh *deviceHandler) GetBackendPathPrefix() string {
4423 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4424}
4425
4426// GetOnuIndication - TODO: add comment
4427func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4428 return dh.pOnuIndication
4429}
4430
4431// RLockMutexDeletionInProgressFlag - TODO: add comment
4432func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4433 dh.mutexDeletionInProgressFlag.RLock()
4434}
4435
4436// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4437func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4438 dh.mutexDeletionInProgressFlag.RUnlock()
4439}
4440
4441// GetDeletionInProgress - TODO: add comment
4442func (dh *deviceHandler) GetDeletionInProgress() bool {
4443 return dh.deletionInProgress
4444}
4445
4446// GetPmConfigs - TODO: add comment
4447func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4448 return dh.pmConfigs
4449}
4450
4451// GetDeviceType - TODO: add comment
4452func (dh *deviceHandler) GetDeviceType() string {
4453 return dh.DeviceType
4454}
4455
4456// GetLogicalDeviceID - TODO: add comment
4457func (dh *deviceHandler) GetLogicalDeviceID() string {
4458 return dh.logicalDeviceID
4459}
4460
4461// GetDevice - TODO: add comment
4462func (dh *deviceHandler) GetDevice() *voltha.Device {
4463 return dh.device
4464}
4465
4466// GetMetricsEnabled - TODO: add comment
4467func (dh *deviceHandler) GetMetricsEnabled() bool {
4468 return dh.pOpenOnuAc.MetricsEnabled
4469}
4470
4471// InitPmConfigs - TODO: add comment
4472func (dh *deviceHandler) InitPmConfigs() {
4473 dh.pmConfigs = &voltha.PmConfigs{}
4474}
4475
4476// GetUniPortMask - TODO: add comment
4477func (dh *deviceHandler) GetUniPortMask() int {
4478 return dh.pOpenOnuAc.config.UniPortMask
4479}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00004480
4481func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
4482 tpPathFound := false
4483 for _, tpPath := range aTpPathMap {
4484 if tpPath != "" {
4485 tpPathFound = true
4486 }
4487 }
4488 return tpPathFound
4489}