blob: f1005e69be92606688bb3de9ef24ec1667d73564 [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"
khenaidoo42dcdfd2021-10-19 17:34:12 -040050 ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040051 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
mpagenko59862f02021-10-11 08:53:18 +000052 "github.com/opencord/voltha-protos/v5/go/openolt"
khenaidoo7d3c5582021-08-11 18:09:44 -040053 oop "github.com/opencord/voltha-protos/v5/go/openolt"
mpagenko59862f02021-10-11 08:53:18 +000054 "github.com/opencord/voltha-protos/v5/go/tech_profile"
khenaidoo7d3c5582021-08-11 18:09:44 -040055 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000056)
57
mpagenko38662d02021-08-11 09:45:19 +000058// Constants for timeouts
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000059const (
mpagenko38662d02021-08-11 09:45:19 +000060 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000061)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000062
mpagenko1cc3cb42020-07-27 15:24:38 +000063const (
mpagenko44bd8362021-11-15 11:40:05 +000064 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
65 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
66 // as long as such is not available by the libraries - use this workaround
67 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
68)
69
70const (
mpagenko1cc3cb42020-07-27 15:24:38 +000071 // events of Device FSM
72 devEvDeviceInit = "devEvDeviceInit"
73 devEvGrpcConnected = "devEvGrpcConnected"
74 devEvGrpcDisconnected = "devEvGrpcDisconnected"
75 devEvDeviceUpInd = "devEvDeviceUpInd"
76 devEvDeviceDownInd = "devEvDeviceDownInd"
77)
78const (
79 // states of Device FSM
80 devStNull = "devStNull"
81 devStDown = "devStDown"
82 devStInit = "devStInit"
83 devStConnected = "devStConnected"
84 devStUp = "devStUp"
85)
86
Holger Hildebrandt24d51952020-05-04 14:03:42 +000087//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
88const (
Himani Chawla4d908332020-08-31 12:30:20 +053089 pon = voltha.EventSubCategory_PON
90 //olt = voltha.EventSubCategory_OLT
91 //ont = voltha.EventSubCategory_ONT
92 //onu = voltha.EventSubCategory_ONU
93 //nni = voltha.EventSubCategory_NNI
94 //service = voltha.EventCategory_SERVICE
95 //security = voltha.EventCategory_SECURITY
96 equipment = voltha.EventCategory_EQUIPMENT
97 //processing = voltha.EventCategory_PROCESSING
98 //environment = voltha.EventCategory_ENVIRONMENT
99 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000100)
101
102const (
103 cEventObjectType = "ONU"
104)
105const (
106 cOnuActivatedEvent = "ONU_ACTIVATED"
107)
108
mpagenkof1fc3862021-02-16 10:09:52 +0000109type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000110 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000111 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000112}
113
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000114var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
115 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
116 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
117 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
118 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
119 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
120 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
121 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
122 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000123}
124
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000125const (
126 cNoReconciling = iota
127 cOnuConfigReconciling
128 cSkipOnuConfigReconciling
129)
130
Girish Gowdrae95687a2021-09-08 16:30:58 -0700131// FlowCb is the flow control block containing flow add/delete information along with a response channel
132type FlowCb struct {
133 ctx context.Context // Flow handler context
134 addFlow bool // if true flow to be added, else removed
135 flowItem *of.OfpFlowStats
136 uniPort *cmn.OnuUniPort
khenaidoo42dcdfd2021-10-19 17:34:12 -0400137 flowMetaData *of.FlowMetadata
Girish Gowdrae95687a2021-09-08 16:30:58 -0700138 respChan *chan error // channel to report the Flow handling error
139}
140
Himani Chawla6d2ae152020-09-02 13:11:20 +0530141//deviceHandler will interact with the ONU ? device.
142type deviceHandler struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000143 DeviceID string
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000144 DeviceType string
145 adminState string
146 device *voltha.Device
147 logicalDeviceID string
148 ProxyAddressID string
149 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530150 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000151 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000152
khenaidoo7d3c5582021-08-11 18:09:44 -0400153 coreClient *vgrpc.Client
154 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000155
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800156 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400157 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800158
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000159 pOpenOnuAc *OpenONUAC
160 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530161 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000162 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000163 pOnuOmciDevice *mib.OnuDeviceEntry
164 pOnuTP *avcfg.OnuUniTechProf
165 pOnuMetricsMgr *pmmgr.OnuMetricsManager
166 pAlarmMgr *almgr.OnuAlarmManager
167 pSelfTestHdlr *otst.SelfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000168 exitChannel chan int
169 lockDevice sync.RWMutex
170 pOnuIndication *oop.OnuIndication
171 deviceReason uint8
172 mutexDeviceReason sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000173 pLockStateFsm *uniprt.LockStateFsm
174 pUnlockStateFsm *uniprt.LockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000175
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000176 //flowMgr *OpenOltFlowMgr
177 //eventMgr *OpenOltEventMgr
178 //resourceMgr *rsrcMgr.OpenOltResourceMgr
179
180 //discOnus sync.Map
181 //onus sync.Map
182 //portStats *OpenOltStatisticsMgr
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000183 collectorIsRunning bool
184 mutexCollectorFlag sync.RWMutex
185 stopCollector chan bool
186 alarmManagerIsRunning bool
187 mutextAlarmManagerFlag sync.RWMutex
188 stopAlarmManager chan bool
189 stopHeartbeatCheck chan bool
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000190 uniEntityMap cmn.OnuUniPortMap
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000191 mutexKvStoreContext sync.Mutex
192 lockVlanConfig sync.RWMutex
mpagenkobc4170a2021-08-17 16:42:10 +0000193 lockVlanAdd sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000194 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000195 lockUpgradeFsm sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000196 pOnuUpradeFsm *swupg.OnuUpgradeFsm
mpagenko59862f02021-10-11 08:53:18 +0000197 upgradeCanceled bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000198 reconciling uint8
199 mutexReconcilingFlag sync.RWMutex
200 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000201 mutexReadyForOmciConfig sync.RWMutex
202 readyForOmciConfig bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000203 deletionInProgress bool
204 mutexDeletionInProgressFlag sync.RWMutex
mpagenko38662d02021-08-11 09:45:19 +0000205 pLastUpgradeImageState *voltha.ImageState
206 upgradeFsmChan chan struct{}
Girish Gowdrae95687a2021-09-08 16:30:58 -0700207
208 flowCbChan []chan FlowCb
209 mutexFlowMonitoringRoutineFlag sync.RWMutex
210 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
211 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000212}
213
Himani Chawla6d2ae152020-09-02 13:11:20 +0530214//newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400215func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530216 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400217 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000218 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400219 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000220 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000221 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000222 dh.DeviceType = cloned.Type
223 dh.adminState = "up"
224 dh.device = cloned
225 dh.pOpenOnuAc = adapter
226 dh.exitChannel = make(chan int, 1)
227 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000228 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000229 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000230 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530231 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530232 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000233 dh.stopHeartbeatCheck = make(chan bool, 2)
234 //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 +0000235 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000236 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000237 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000238 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000239 dh.lockUpgradeFsm = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000240 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000241 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000242 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000243 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000244 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000245 dh.pLastUpgradeImageState = &voltha.ImageState{
246 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
247 Reason: voltha.ImageState_UNKNOWN_ERROR,
248 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
249 }
250 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000251
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800252 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
253 dh.pmConfigs = cloned.PmConfigs
254 } /* else {
255 // will be populated when onu_metrics_mananger is initialized.
256 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800257
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000258 // Device related state machine
259 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000260 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000261 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000262 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
263 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
264 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
265 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
266 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000267 },
268 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000269 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
270 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
271 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
272 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
273 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
274 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
275 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
276 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000277 },
278 )
mpagenkoaf801632020-07-03 10:00:42 +0000279
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000280 return &dh
281}
282
Himani Chawla6d2ae152020-09-02 13:11:20 +0530283// start save the device to the data model
284func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000285 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000287 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000288}
289
Himani Chawla4d908332020-08-31 12:30:20 +0530290/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000291// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530292func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000293 logger.Debug("stopping-device-handler")
294 dh.exitChannel <- 1
295}
Himani Chawla4d908332020-08-31 12:30:20 +0530296*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297
298// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530299// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000300
Girish Gowdrae0140f02021-02-02 16:55:09 -0800301//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530302func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400303 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000304
dbainbri4d3a0dc2020-12-02 00:33:42 +0000305 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000306 if dh.pDeviceStateFsm.Is(devStNull) {
307 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000308 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000309 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000310 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800311 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
312 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800313 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400314 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000315 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800316 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800317 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000318 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000319 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000320 }
321
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000322}
323
khenaidoo42dcdfd2021-10-19 17:34:12 -0400324func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000325 /* 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 +0530326 //assuming omci message content is hex coded!
327 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000328 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000329 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000330 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000331 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530332 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000333 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000334 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000335 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400336 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530337 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000338 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
339 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530340}
341
khenaidoo42dcdfd2021-10-19 17:34:12 -0400342func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000343 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000344
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000345 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000346 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000347 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
348 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000349 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530350 if dh.pOnuTP == nil {
351 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000352 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000353 log.Fields{"device-id": dh.DeviceID})
354 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530355 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000356 if !dh.IsReadyForOmciConfig() {
357 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
358 "device-state": dh.GetDeviceReasonString()})
359 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530360 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000361 //previous state test here was just this one, now extended for more states to reject the SetRequest:
362 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
363 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530364
Himani Chawla26e555c2020-08-31 12:30:20 +0530365 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000366 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
367 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000368 dh.pOnuTP.LockTpProcMutex()
369 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000370
mpagenko44bd8362021-11-15 11:40:05 +0000371 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000372 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000373 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000374 }
375 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000376 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800377 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700378 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800379 return err
380 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700381 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000382
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000383 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530384
Girish Gowdra50e56422021-06-01 16:46:04 -0700385 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400386 case *ia.TechProfileDownloadMessage_TpInstance:
Girish Gowdra50e56422021-06-01 16:46:04 -0700387 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
388 // if there has been some change for some uni TechProfilePath
389 //in order to allow concurrent calls to other dh instances we do not wait for execution here
390 //but doing so we can not indicate problems to the caller (who does what with that then?)
391 //by now we just assume straightforward successful execution
392 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
393 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530394
Girish Gowdra50e56422021-06-01 16:46:04 -0700395 // deadline context to ensure completion of background routines waited for
396 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
397 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
398 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000399
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000400 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700401
402 var wg sync.WaitGroup
403 wg.Add(1) // for the 1 go routine to finish
404 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000405 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700406 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000407 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
408 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 -0700409 return tpErr
410 }
411 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
412 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000413 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700414 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000415 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700416 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000417 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
418 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 -0700419 return kvErr
420 }
421 return nil
422 default:
423 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"tp-path": techProfMsg.TpInstancePath})
424 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700425 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530426 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000427 // no change, nothing really to do - return success
Girish Gowdra50e56422021-06-01 16:46:04 -0700428 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530429 return nil
430}
431
khenaidoo42dcdfd2021-10-19 17:34:12 -0400432func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000433 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530434
435 if dh.pOnuTP == nil {
436 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000437 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000438 log.Fields{"device-id": dh.DeviceID})
439 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530440 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530441 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000442 dh.pOnuTP.LockTpProcMutex()
443 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530444
mpagenko0f543222021-11-03 16:24:14 +0000445 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
446 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
447 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000448 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000449 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000450 }
451 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000452 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800453 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000454 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
455 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800456 return err
457 }
mpagenko0f543222021-11-03 16:24:14 +0000458 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
459 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000460 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000461
Mahir Gunyel9545be22021-07-04 15:53:16 -0700462 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000463 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000464
Himani Chawla26e555c2020-08-31 12:30:20 +0530465}
466
khenaidoo42dcdfd2021-10-19 17:34:12 -0400467func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000468 logger.Infow(ctx, "delete-tcont-request start", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000469
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000470 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000471 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000472 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
473 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000474 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530475 if dh.pOnuTP == nil {
476 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000477 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000478 log.Fields{"device-id": dh.DeviceID})
479 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530480 }
481
Himani Chawla26e555c2020-08-31 12:30:20 +0530482 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000483 dh.pOnuTP.LockTpProcMutex()
484 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000485
mpagenko0f543222021-11-03 16:24:14 +0000486 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
487 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
488 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000489 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000490 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000491 }
492 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700493 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000494 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800495 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000496 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
497 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800498 return err
499 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000500 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 +0000501
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000502 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530503
Mahir Gunyel9545be22021-07-04 15:53:16 -0700504 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000505 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000506
Mahir Gunyel9545be22021-07-04 15:53:16 -0700507}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000508
Mahir Gunyel9545be22021-07-04 15:53:16 -0700509func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000510 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
511 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700512 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000513 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
514 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530515 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700516 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000517 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700518 resourceName = "Gem"
519 } else {
520 resourceName = "Tcont"
521 }
522
523 // deadline context to ensure completion of background routines waited for
524 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
525 dctx, cancel := context.WithDeadline(context.Background(), deadline)
526
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000527 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700528
529 var wg sync.WaitGroup
530 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000531 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700532 resource, entryID, &wg)
533 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000534 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
535 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700536 return err
537 }
538
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000539 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
540 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
541 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
542 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700543 var wg2 sync.WaitGroup
544 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
545 wg2.Add(1)
546 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000547 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
548 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700549 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000550 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
551 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700552 return err
553 }
554 }
555 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000556 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700557 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530558 return nil
559}
560
mpagenkodff5dda2020-08-28 11:52:01 +0000561//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000562func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400563 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400564 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700565 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
566 var errorsList []error
567 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000568 //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 +0000569 if apOfFlowChanges.ToRemove != nil {
570 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000571 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000572 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000573 "device-id": dh.DeviceID})
574 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700575 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000576 continue
577 }
578 flowInPort := flow.GetInPort(flowItem)
579 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000580 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
581 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700582 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000583 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000584 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000585 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000586 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000587 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000588 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000589 continue
590 } else {
591 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000592 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000593 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
594 loUniPort = uniPort
595 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000596 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000597 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000598 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000599 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700600 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000601 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000602 }
603 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000604 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000605 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
606 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700607
608 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
609 // Step1 : Fill flowControlBlock
610 // Step2 : Push the flowControlBlock to ONU channel
611 // Step3 : Wait on response channel for response
612 // Step4 : Return error value
613 startTime := time.Now()
614 respChan := make(chan error)
615 flowCb := FlowCb{
616 ctx: ctx,
617 addFlow: false,
618 flowItem: flowItem,
619 flowMetaData: nil,
620 uniPort: loUniPort,
621 respChan: &respChan,
622 }
623 dh.flowCbChan[loUniPort.UniID] <- flowCb
624 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
625 // Wait on the channel for flow handlers return value
626 retError = <-respChan
627 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
628 if retError != nil {
629 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
630 log.Fields{"device-id": dh.DeviceID, "error": retError})
631 errorsList = append(errorsList, retError)
632 continue
633 }
634 } else {
635 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
636 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000637 }
638 }
639 }
640 }
mpagenko01e726e2020-10-23 09:45:29 +0000641 if apOfFlowChanges.ToAdd != nil {
642 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
643 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000644 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000645 "device-id": dh.DeviceID})
646 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700647 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000648 continue
649 }
650 flowInPort := flow.GetInPort(flowItem)
651 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000652 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
653 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700654 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000655 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000656 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000657 } else if flowInPort == dh.ponPortNumber {
658 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000659 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000660 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000661 continue
662 } else {
663 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000664 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000665 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
666 loUniPort = uniPort
667 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000668 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000669 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000670 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000671 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700672 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000673 continue
mpagenko01e726e2020-10-23 09:45:29 +0000674 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000675 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
676 // if not, we just throw some error here to have an indication about that, if we really need to support that
677 // then we would need to create some means to activate the internal stored flows
678 // after the device gets active automatically (and still with its dependency to the TechProfile)
679 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
680 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000681 if !dh.IsReadyForOmciConfig() {
682 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
683 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700684 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
685 errorsList = append(errorsList, retError)
686 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000687 }
688
mpagenko01e726e2020-10-23 09:45:29 +0000689 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000690 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000691 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
692 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700693 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
694 // Step1 : Fill flowControlBlock
695 // Step2 : Push the flowControlBlock to ONU channel
696 // Step3 : Wait on response channel for response
697 // Step4 : Return error value
698 startTime := time.Now()
699 respChan := make(chan error)
700 flowCb := FlowCb{
701 ctx: ctx,
702 addFlow: true,
703 flowItem: flowItem,
704 flowMetaData: apFlowMetaData,
705 uniPort: loUniPort,
706 respChan: &respChan,
707 }
708 dh.flowCbChan[loUniPort.UniID] <- flowCb
709 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
710 // Wait on the channel for flow handlers return value
711 retError = <-respChan
712 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
713 if retError != nil {
714 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
715 log.Fields{"device-id": dh.DeviceID, "error": retError})
716 errorsList = append(errorsList, retError)
717 continue
718 }
719 } else {
720 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
721 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000722 }
723 }
724 }
725 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700726 if len(errorsList) > 0 {
727 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
728 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
729 }
730 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000731}
732
Himani Chawla6d2ae152020-09-02 13:11:20 +0530733//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000734//following are the expected device states after this activity:
735//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
736// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000737func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
738 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000739
mpagenko900ee4b2020-10-12 11:56:34 +0000740 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000741 //note that disableDevice sequences in some 'ONU active' state may yield also
742 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000743 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000744 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000745 //disable-device shall be just a UNi/ONU-G related admin state setting
746 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000747
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000748 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000749 // disable UNI ports/ONU
750 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
751 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000752 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000753 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000754 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000755 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000756 }
757 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000758 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000759 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000760 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400761 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000762 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000763 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400764 OperStatus: voltha.OperStatus_UNKNOWN,
765 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000766 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000767 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000768 }
mpagenko01e726e2020-10-23 09:45:29 +0000769 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000770
771 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000772 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000773 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300774 }
775}
776
Himani Chawla6d2ae152020-09-02 13:11:20 +0530777//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000778func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
779 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000780
mpagenkoaa3afe92021-05-21 16:20:58 +0000781 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000782 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
783 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
784 // for real ONU's that should have nearly no influence
785 // Note that for real ONU's there is anyway a problematic situation with following sequence:
786 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
787 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
788 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000789 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000790
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000791 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000792 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000793 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000794 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000795 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000796 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000797 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000798 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300799}
800
dbainbri4d3a0dc2020-12-02 00:33:42 +0000801func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000802 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000803
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000804 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000805 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000806 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000807 return
808 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000809 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000810 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000811 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000812 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000813 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000814 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000815 dh.StopReconciling(ctx, false)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000816 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000817 }
Himani Chawla4d908332020-08-31 12:30:20 +0530818 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000819 pDevEntry.MutexPersOnuConfig.RLock()
820 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
821 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
822 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
823 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
824 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000825 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000826}
827
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000828func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) {
829 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000830
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000831 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000832 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000833 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
834 if !dh.IsSkipOnuConfigReconciling() {
835 dh.StopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000836 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000837 return
838 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000839 dh.pOnuTP.LockTpProcMutex()
840 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000841
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000842 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000843 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000844 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
845 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000846 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000847 log.Fields{"device-id": dh.DeviceID})
848 if !dh.IsSkipOnuConfigReconciling() {
849 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000850 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000851 return
852 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000853 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700854 techProfsFound := false
855 techProfInstLoadFailed := false
856outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000857 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000858 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
859 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000860 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000861 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000862 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000863 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000864 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
865 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000866 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000867 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000868 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700869 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800870 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700871 // Request the TpInstance again from the openolt adapter in case of reconcile
khenaidoo7d3c5582021-08-11 18:09:44 -0400872 iaTechTpInst, err := dh.getTechProfileInstanceFromParentAdapter(ctx,
873 dh.device.ProxyAddress.AdapterEndpoint,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400874 &ia.TechProfileInstanceRequestMessage{
khenaidoo7d3c5582021-08-11 18:09:44 -0400875 DeviceId: dh.device.Id,
876 TpInstancePath: uniData.PersTpPathMap[tpID],
877 ParentDeviceId: dh.parentID,
878 ParentPonPort: dh.device.ParentPortNo,
879 OnuId: dh.device.ProxyAddress.OnuId,
880 UniId: uint32(uniData.PersUniID),
881 })
Girish Gowdra50e56422021-06-01 16:46:04 -0700882 if err != nil || iaTechTpInst == nil {
883 logger.Errorw(ctx, "error fetching tp instance",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000884 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID, "err": err})
Girish Gowdra50e56422021-06-01 16:46:04 -0700885 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
886 break outerLoop
887 }
888 var tpInst tech_profile.TechProfileInstance
889 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400890 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700891 tpInst = *techTpInst.TpInstance
mpagenko2dc896e2021-08-02 12:03:59 +0000892 logger.Debugw(ctx, "received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000893 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700894 default: // do not support epon or other tech
mpagenko2dc896e2021-08-02 12:03:59 +0000895 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000896 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700897 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
898 break outerLoop
899 }
900
Girish Gowdra041dcb32020-11-16 16:54:30 -0800901 // deadline context to ensure completion of background routines waited for
902 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
903 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000904 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000905
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000906 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800907 var wg sync.WaitGroup
908 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000909 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000910 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000911 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
912 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700913 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
914 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800915 }
mpagenko2dc896e2021-08-02 12:03:59 +0000916 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000917 if len(uniData.PersFlowParams) != 0 {
918 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000919 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000920 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000921 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000922 } // for all UNI entries from SOnuPersistentData
923 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
924 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000925 }
mpagenko2dc896e2021-08-02 12:03:59 +0000926
927 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
928 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
929}
930
931func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
932 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
933 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000934 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000935 log.Fields{"device-id": dh.DeviceID})
936 if !dh.IsSkipOnuConfigReconciling() {
937 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000938 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000939 return
940 }
mpagenko2dc896e2021-08-02 12:03:59 +0000941 if abTechProfInstLoadFailed {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000942 dh.SetDeviceReason(cmn.DrTechProfileConfigDownloadFailed)
943 dh.StopReconciling(ctx, false)
Girish Gowdra50e56422021-06-01 16:46:04 -0700944 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000945 } else if dh.IsSkipOnuConfigReconciling() {
946 dh.SetDeviceReason(cmn.DrTechProfileConfigDownloadSuccess)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000947 }
mpagenko2dc896e2021-08-02 12:03:59 +0000948 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000949 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000950 log.Fields{"device-id": dh.DeviceID})
951 if !dh.IsSkipOnuConfigReconciling() {
952 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000953 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000954 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000955}
956
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000957func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
958 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000959
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000960 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000961 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000962 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
963 if !dh.IsSkipOnuConfigReconciling() {
964 dh.StopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000965 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000966 return
967 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000968
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000969 pDevEntry.MutexPersOnuConfig.RLock()
970 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
971 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000972 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000973 log.Fields{"device-id": dh.DeviceID})
974 if !dh.IsSkipOnuConfigReconciling() {
975 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000976 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000977 return
978 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000979 flowsFound := false
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000980 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000981 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
982 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000983 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000984 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000985 continue
986 }
987 if len(uniData.PersTpPathMap) == 0 {
988 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000989 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000990 // It doesn't make sense to configure any flows if no TPs are available
991 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000992 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000993 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
994 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000995 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000996 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000997
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000998 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000999 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001000 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001001 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001002 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1003 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
1004 if !dh.IsSkipOnuConfigReconciling() {
1005 dh.StopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001006 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001007 return
1008 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001009 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001010 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001011 flowsProcessed := 0
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001012 pDevEntry.SetReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001013 for _, flowData := range uniData.PersFlowParams {
mpagenko2dc896e2021-08-02 12:03:59 +00001014 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001015 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001016 if flowsProcessed == len(uniData.PersFlowParams)-1 {
1017 lastFlowToReconcile = true
1018 }
mpagenko01e726e2020-10-23 09:45:29 +00001019 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenko7d14de12021-07-27 08:31:56 +00001020 dh.lockVlanConfig.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001021 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001022 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +00001023 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Girish Gowdrae95687a2021-09-08 16:30:58 -07001024 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter, nil); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001025 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001026 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001027 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001028 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00001029 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Girish Gowdrae95687a2021-09-08 16:30:58 -07001030 uint8(flowData.VlanRuleParams.SetPcp), cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001031 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001032 }
1033 }
mpagenko7d14de12021-07-27 08:31:56 +00001034 dh.lockVlanConfig.Unlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001035 flowsProcessed++
mpagenko2dc896e2021-08-02 12:03:59 +00001036 } //for all flows of this UNI
1037 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001038 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID, "flowsProcessed": flowsProcessed,
1039 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1040 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001041 // this can't be used as global finished reconciling flag because
1042 // assumes is getting called before the state machines for the last flow is completed,
1043 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001044 //dh.SetReconcilingFlows(false)
1045 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1046 } // for all UNI entries from SOnuPersistentData
1047 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001048
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001049 if !flowsFound {
1050 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001051 log.Fields{"device-id": dh.DeviceID})
1052 if !dh.IsSkipOnuConfigReconciling() {
1053 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001054 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001055 return
1056 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001057 if dh.IsSkipOnuConfigReconciling() {
1058 dh.SetDeviceReason(cmn.DrOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001059 }
1060}
1061
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001062func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001063 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.DeviceID})
1064 dh.StopReconciling(ctx, true)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001065}
1066
dbainbri4d3a0dc2020-12-02 00:33:42 +00001067func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001068 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001069
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001070 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001071 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001072 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001073 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001074 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001075 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001076
1077 // deadline context to ensure completion of background routines waited for
1078 //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 +05301079 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001080 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001081
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001082 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001083
1084 var wg sync.WaitGroup
1085 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001086 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001087 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001088
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001089 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001090 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001091}
1092
mpagenko15ff4a52021-03-02 10:09:20 +00001093//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1094// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001095// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001096//was and is called in background - error return does not make sense
1097func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001098 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001099 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001100 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001101 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001102 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001103 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301104 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001105 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001106 return
Himani Chawla4d908332020-08-31 12:30:20 +05301107 }
mpagenko01e726e2020-10-23 09:45:29 +00001108
1109 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001110 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001111
mpagenko44bd8362021-11-15 11:40:05 +00001112 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001113 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001114 // 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 -04001115 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001116 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001117 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001118 OperStatus: voltha.OperStatus_DISCOVERED,
1119 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001120 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001121 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001122 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001123 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001124 if err := dh.deviceReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001125 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001126 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001127 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001128 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1129 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1130 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1131 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001132}
1133
mpagenkoc8bba412021-01-15 15:38:44 +00001134//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001135// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001136func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001137 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001138 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001139 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001140
1141 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001142 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001143 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001144 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1145 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001146 }
1147
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001148 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001149 var inactiveImageID uint16
1150 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1151 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001152 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1153 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001154 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001155 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001156 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001157 if err == nil {
1158 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1159 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001160 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001161 }
1162 } else {
1163 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001164 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001165 }
mpagenko15ff4a52021-03-02 10:09:20 +00001166 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001167 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001168 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001169 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1170 dh.upgradeCanceled = true
1171 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1172 }
mpagenko38662d02021-08-11 09:45:19 +00001173 //no effort spent anymore for the old API to automatically cancel and restart the download
1174 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001175 }
mpagenko15ff4a52021-03-02 10:09:20 +00001176 } else {
1177 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001178 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001179 }
1180 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001181 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1182 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001183 }
1184 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001185}
1186
mpagenkoc26d4c02021-05-06 14:27:57 +00001187//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1188// after the OnuImage has been downloaded to the adapter, called in background
1189func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001190 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001191
1192 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001193 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001194 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001195 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001196 return
1197 }
1198
1199 var inactiveImageID uint16
1200 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1201 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001202 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001203
mpagenko59862f02021-10-11 08:53:18 +00001204 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001205 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001206 // but must be still locked at calling createOnuUpgradeFsm
1207 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1208 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1209 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001210 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1211 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001212 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001213 //flush the remove upgradeFsmChan channel
1214 select {
1215 case <-dh.upgradeFsmChan:
1216 logger.Debug(ctx, "flushed-upgrade-fsm-channel")
1217 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001218 }
mpagenko59862f02021-10-11 08:53:18 +00001219 dh.lockUpgradeFsm.Unlock()
1220 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1221 dh.upgradeCanceled = true
1222 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1223 }
mpagenko38662d02021-08-11 09:45:19 +00001224 select {
1225 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001226 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001227 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1228 return
1229 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001230 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001231 }
mpagenko59862f02021-10-11 08:53:18 +00001232 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001233 }
mpagenko38662d02021-08-11 09:45:19 +00001234
1235 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001236 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001237 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001238 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001239 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001240 if err == nil {
1241 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1242 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1243 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001244 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001245 return
1246 }
mpagenko38662d02021-08-11 09:45:19 +00001247 } else {
1248 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001249 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001250 }
1251 return
1252 }
1253 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001254 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001255}
1256
1257//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001258func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1259 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001260 var err error
1261 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1262 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1263 // 2.) activation of the inactive image
1264
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001265 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001266 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001267 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1268 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001269 }
1270 dh.lockUpgradeFsm.RLock()
1271 if dh.pOnuUpradeFsm != nil {
1272 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001273 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001274 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001275 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1276 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001277 }
mpagenko59862f02021-10-11 08:53:18 +00001278 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1279 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1280 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1281 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001282 // use the OnuVendor identification from this device for the internal unique name
1283 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001284 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001285 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001286 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001287 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001288 "device-id": dh.DeviceID, "error": err})
1289 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001290 }
mpagenko183647c2021-06-08 15:25:04 +00001291 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001292 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001293 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001294 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001295 } //else
1296 dh.lockUpgradeFsm.RUnlock()
1297
1298 // 2.) check if requested image-version equals the inactive one and start its activation
1299 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1300 var inactiveImageID uint16
1301 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1302 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001303 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1304 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001305 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001306 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001307 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001308 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001309 if err == nil {
1310 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1311 inactiveImageID, aCommitRequest); err != nil {
1312 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001313 "device-id": dh.DeviceID, "error": err})
1314 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001315 }
1316 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001317 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001318 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001319 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001320 } //else
1321 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001322 "device-id": dh.DeviceID, "error": err})
1323 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001324}
1325
1326//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001327func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1328 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001329 var err error
1330 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1331 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1332 // 2.) commitment of the active image
1333
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001334 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001335 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001336 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1337 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001338 }
1339 dh.lockUpgradeFsm.RLock()
1340 if dh.pOnuUpradeFsm != nil {
1341 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001342 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001343 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001344 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1345 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001346 }
mpagenko59862f02021-10-11 08:53:18 +00001347 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1348 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1349 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1350 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001351 // use the OnuVendor identification from this device for the internal unique name
1352 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001353 // 1.) check a started upgrade process and relay the commitment request to it
1354 // the running upgrade may be based either on the imageIdentifier (started from download)
1355 // or on the imageVersion (started from pure activation)
1356 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1357 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001358 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001359 "device-id": dh.DeviceID, "error": err})
1360 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001361 }
mpagenko183647c2021-06-08 15:25:04 +00001362 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001363 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001364 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001365 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001366 } //else
1367 dh.lockUpgradeFsm.RUnlock()
1368
mpagenko183647c2021-06-08 15:25:04 +00001369 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001370 var activeImageID uint16
1371 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1372 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001373 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1374 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001375 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001376 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001377 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001378 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001379 if err == nil {
1380 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1381 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001382 "device-id": dh.DeviceID, "error": err})
1383 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001384 }
1385 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001386 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001387 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001388 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001389 } //else
1390 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001391 "device-id": dh.DeviceID, "error": err})
1392 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001393}
1394
mpagenkoaa3afe92021-05-21 16:20:58 +00001395func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001396 aVersion string) *voltha.ImageState {
1397 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001398 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001399 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001400 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001401 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1402 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1403 if aVersion == dh.pLastUpgradeImageState.Version {
1404 pImageState = dh.pLastUpgradeImageState
1405 } else { //state request for an image version different from last processed image version
1406 pImageState = &voltha.ImageState{
1407 Version: aVersion,
1408 //we cannot state something concerning this version
1409 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1410 Reason: voltha.ImageState_NO_ERROR,
1411 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1412 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001413 }
1414 }
mpagenko38662d02021-08-11 09:45:19 +00001415 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001416}
1417
1418func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1419 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001420 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001421 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001422 dh.lockUpgradeFsm.RLock()
1423 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001424 dh.lockUpgradeFsm.RUnlock()
1425 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001426 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001427 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1428 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1429 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1430 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1431 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1432 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001433 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1434 dh.upgradeCanceled = true
1435 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1436 }
mpagenko45586762021-10-01 08:30:22 +00001437 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001438 } else {
mpagenko45586762021-10-01 08:30:22 +00001439 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001440 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1441 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1442 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1443 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1444 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1445 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001446 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1447 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001448 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1449 //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 +00001450 }
1451}
1452
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001453func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1454
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001455 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001456
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001457 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001458 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001459 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1460 pDevEntry.MutexOnuImageStatus.Lock()
1461 pDevEntry.POnuImageStatus = onuImageStatus
1462 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001463
1464 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001465 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001466 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1467 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001468 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1469 pDevEntry.MutexOnuImageStatus.Lock()
1470 pDevEntry.POnuImageStatus = nil
1471 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001472 return images, err
1473}
1474
Himani Chawla6d2ae152020-09-02 13:11:20 +05301475// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001476// #####################################################################################
1477
1478// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301479// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001480
dbainbri4d3a0dc2020-12-02 00:33:42 +00001481func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001482 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event), "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001483}
1484
1485// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001486func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001487
dbainbri4d3a0dc2020-12-02 00:33:42 +00001488 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001489 var err error
1490
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001491 // populate what we know. rest comes later after mib sync
1492 dh.device.Root = false
1493 dh.device.Vendor = "OpenONU"
1494 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001495 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
1496 dh.SetDeviceReason(cmn.DrActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001497
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001498 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001499
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001500 if !dh.IsReconciling() {
1501 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001502 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1503 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1504 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301505 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001506 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001507 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001508 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001509 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001510
Himani Chawla4d908332020-08-31 12:30:20 +05301511 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001512 dh.ponPortNumber = dh.device.ParentPortNo
1513
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001514 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1515 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1516 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001517 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001518 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301519 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001520
1521 /*
1522 self._pon = PonPort.create(self, self._pon_port_number)
1523 self._pon.add_peer(self.parent_id, self._pon_port_number)
1524 self.logger.debug('adding-pon-port-to-agent',
1525 type=self._pon.get_port().type,
1526 admin_state=self._pon.get_port().admin_state,
1527 oper_status=self._pon.get_port().oper_status,
1528 )
1529 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001530 if !dh.IsReconciling() {
1531 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001532 var ponPortNo uint32 = 1
1533 if dh.ponPortNumber != 0 {
1534 ponPortNo = dh.ponPortNumber
1535 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001536
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001537 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001538 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001539 PortNo: ponPortNo,
1540 Label: fmt.Sprintf("pon-%d", ponPortNo),
1541 Type: voltha.Port_PON_ONU,
1542 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301543 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001544 PortNo: ponPortNo}}, // Peer port is parent's port number
1545 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001546 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001547 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001548 e.Cancel(err)
1549 return
1550 }
1551 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001552 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001553 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001554 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001555}
1556
1557// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001558func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001559
dbainbri4d3a0dc2020-12-02 00:33:42 +00001560 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001561 var err error
1562 /*
1563 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1564 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1565 return nil
1566 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001567 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1568 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001569 e.Cancel(err)
1570 return
1571 }
1572
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001573 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001574 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001575 // reconcilement will be continued after mib download is done
1576 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001577
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001578 /*
1579 ############################################################################
1580 # Setup Alarm handler
1581 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1582 device.serial_number)
1583 ############################################################################
1584 # Setup PM configuration for this device
1585 # Pass in ONU specific options
1586 kwargs = {
1587 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1588 'heartbeat': self.heartbeat,
1589 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1590 }
1591 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1592 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1593 self.logical_device_id, device.serial_number,
1594 grouped=True, freq_override=False, **kwargs)
1595 pm_config = self._pm_metrics.make_proto()
1596 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1597 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1598 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1599
1600 # Note, ONU ID and UNI intf set in add_uni_port method
1601 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1602 ani_ports=[self._pon])
1603
1604 # Code to Run OMCI Test Action
1605 kwargs_omci_test_action = {
1606 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1607 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1608 }
1609 serial_number = device.serial_number
1610 self._test_request = OmciTestRequest(self.core_proxy,
1611 self.omci_agent, self.device_id,
1612 AniG, serial_number,
1613 self.logical_device_id,
1614 exclusive=False,
1615 **kwargs_omci_test_action)
1616
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001617 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001618 else:
1619 self.logger.info('onu-already-activated')
1620 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001621
dbainbri4d3a0dc2020-12-02 00:33:42 +00001622 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001623}
1624
1625// doStateConnected get the device info and update to voltha core
1626// for comparison of the original method (not that easy to uncomment): compare here:
1627// voltha-openolt-adapter/adaptercore/device_handler.go
1628// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001629func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001630
dbainbri4d3a0dc2020-12-02 00:33:42 +00001631 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301632 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001633 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001634 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001635}
1636
1637// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001638func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001639
dbainbri4d3a0dc2020-12-02 00:33:42 +00001640 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301641 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001642 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001643 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001644
1645 /*
1646 // Synchronous call to update device state - this method is run in its own go routine
1647 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1648 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001649 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 +00001650 return err
1651 }
1652 return nil
1653 */
1654}
1655
1656// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001657func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001658
dbainbri4d3a0dc2020-12-02 00:33:42 +00001659 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001660 var err error
1661
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001662 device := dh.device
1663 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001664 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001665 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001666 e.Cancel(err)
1667 return
1668 }
1669
1670 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001671 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001672 /*
1673 // Update the all ports state on that device to disable
1674 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001675 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001676 return er
1677 }
1678
1679 //Update the device oper state and connection status
1680 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1681 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1682 dh.device = cloned
1683
1684 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001685 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001686 return er
1687 }
1688
1689 //get the child device for the parent device
1690 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1691 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001692 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001693 return err
1694 }
1695 for _, onuDevice := range onuDevices.Items {
1696
1697 // Update onu state as down in onu adapter
1698 onuInd := oop.OnuIndication{}
1699 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001700 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001701 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1702 if er != nil {
1703 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001704 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001705 //Do not return here and continue to process other ONUs
1706 }
1707 }
1708 // * Discovered ONUs entries need to be cleared , since after OLT
1709 // is up, it starts sending discovery indications again* /
1710 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001711 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001712 return nil
1713 */
Himani Chawla4d908332020-08-31 12:30:20 +05301714 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001715 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001716 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001717}
1718
Himani Chawla6d2ae152020-09-02 13:11:20 +05301719// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001720// #################################################################################
1721
1722// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301723// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001724
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001725//GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
1726func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001727 dh.lockDevice.RLock()
1728 pOnuDeviceEntry := dh.pOnuOmciDevice
1729 if aWait && pOnuDeviceEntry == nil {
1730 //keep the read sema short to allow for subsequent write
1731 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001732 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001733 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1734 // so it might be needed to wait here for that event with some timeout
1735 select {
1736 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001737 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001738 return nil
1739 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001740 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001741 // if written now, we can return the written value without sema
1742 return dh.pOnuOmciDevice
1743 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001744 }
mpagenko3af1f032020-06-10 08:53:41 +00001745 dh.lockDevice.RUnlock()
1746 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001747}
1748
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001749//setDeviceHandlerEntries sets the ONU device entry within the handler
1750func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1751 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001752 dh.lockDevice.Lock()
1753 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001754 dh.pOnuOmciDevice = apDeviceEntry
1755 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001756 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301757 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001758 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001759}
1760
Himani Chawla6d2ae152020-09-02 13:11:20 +05301761//addOnuDeviceEntry creates a new ONU device or returns the existing
1762func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001763 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001764
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001765 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001766 if deviceEntry == nil {
1767 /* costum_me_map in python code seems always to be None,
1768 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1769 /* also no 'clock' argument - usage open ...*/
1770 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001771 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1772 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1773 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1774 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1775 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001776 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001777 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001778 // fire deviceEntry ready event to spread to possibly waiting processing
1779 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001780 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001781 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001782 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001783 }
1784 // might be updated with some error handling !!!
1785 return nil
1786}
1787
dbainbri4d3a0dc2020-12-02 00:33:42 +00001788func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1789 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001790 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1791
1792 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001793
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001794 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001795 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001796 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1797 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001798 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001799 if !dh.IsReconciling() {
1800 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001801 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001802 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001803 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001804 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001805 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001806
khenaidoo42dcdfd2021-10-19 17:34:12 -04001807 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001808 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001809 OperStatus: voltha.OperStatus_ACTIVATING,
1810 ConnStatus: voltha.ConnectStatus_REACHABLE,
1811 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001812 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001813 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001814 }
1815 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001816 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001817 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001818
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001819 pDevEntry.MutexPersOnuConfig.RLock()
1820 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1821 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001822 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 +00001823 log.Fields{"device-id": dh.DeviceID})
1824 dh.StopReconciling(ctx, true)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001825 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001826 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001827 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001828 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001829 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1830 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1831 // 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 +00001832 // 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 +00001833 // so let's just try to keep it simple ...
1834 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001835 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001836 if err != nil || device == nil {
1837 //TODO: needs to handle error scenarios
1838 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1839 return errors.New("Voltha Device not found")
1840 }
1841 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001842
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001843 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001844 return err
mpagenko3af1f032020-06-10 08:53:41 +00001845 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001846
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001847 _ = dh.deviceReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001848
1849 /* this might be a good time for Omci Verify message? */
1850 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001851 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001852 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001853 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001854 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001855
1856 /* give the handler some time here to wait for the OMCi verification result
1857 after Timeout start and try MibUpload FSM anyway
1858 (to prevent stopping on just not supported OMCI verification from ONU) */
1859 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001860 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001861 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001862 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001863 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001864 }
1865
1866 /* In py code it looks earlier (on activate ..)
1867 # Code to Run OMCI Test Action
1868 kwargs_omci_test_action = {
1869 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1870 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1871 }
1872 serial_number = device.serial_number
1873 self._test_request = OmciTestRequest(self.core_proxy,
1874 self.omci_agent, self.device_id,
1875 AniG, serial_number,
1876 self.logical_device_id,
1877 exclusive=False,
1878 **kwargs_omci_test_action)
1879 ...
1880 # Start test requests after a brief pause
1881 if not self._test_request_started:
1882 self._test_request_started = True
1883 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1884 reactor.callLater(tststart, self._test_request.start_collector)
1885
1886 */
1887 /* which is then: in omci_test_request.py : */
1888 /*
1889 def start_collector(self, callback=None):
1890 """
1891 Start the collection loop for an adapter if the frequency > 0
1892
1893 :param callback: (callable) Function to call to collect PM data
1894 """
1895 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1896 if callback is None:
1897 callback = self.perform_test_omci
1898
1899 if self.lc is None:
1900 self.lc = LoopingCall(callback)
1901
1902 if self.default_freq > 0:
1903 self.lc.start(interval=self.default_freq / 10)
1904
1905 def perform_test_omci(self):
1906 """
1907 Perform the initial test request
1908 """
1909 ani_g_entities = self._device.configuration.ani_g_entities
1910 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1911 is not None else None
1912 self._entity_id = ani_g_entities_ids[0]
1913 self.logger.info('perform-test', entity_class=self._entity_class,
1914 entity_id=self._entity_id)
1915 try:
1916 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1917 result = yield self._device.omci_cc.send(frame)
1918 if not result.fields['omci_message'].fields['success_code']:
1919 self.logger.info('Self-Test Submitted Successfully',
1920 code=result.fields[
1921 'omci_message'].fields['success_code'])
1922 else:
1923 raise TestFailure('Test Failure: {}'.format(
1924 result.fields['omci_message'].fields['success_code']))
1925 except TimeoutError as e:
1926 self.deferred.errback(failure.Failure(e))
1927
1928 except Exception as e:
1929 self.logger.exception('perform-test-Error', e=e,
1930 class_id=self._entity_class,
1931 entity_id=self._entity_id)
1932 self.deferred.errback(failure.Failure(e))
1933
1934 */
1935
1936 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001937 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001938
mpagenko1cc3cb42020-07-27 15:24:38 +00001939 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1940 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1941 * 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 +05301942 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001943 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001944 //call MibUploadFSM - transition up to state UlStInSync
1945 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001946 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001947 if pMibUlFsm.Is(mib.UlStDisabled) {
1948 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
1949 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
1950 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301951 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001952 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301953 //Determine ONU status and start/re-start MIB Synchronization tasks
1954 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001955 if pDevEntry.IsNewOnu() {
1956 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
1957 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
1958 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001959 }
Himani Chawla4d908332020-08-31 12:30:20 +05301960 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001961 if err := pMibUlFsm.Event(mib.UlEvExamineMds); err != nil {
1962 logger.Errorw(ctx, "MibSyncFsm: Can't go to state examine_mds", log.Fields{"device-id": dh.DeviceID, "err": err})
1963 return fmt.Errorf("can't go to examine_mds: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301964 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001965 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001966 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001967 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001968 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001969 "device-id": dh.DeviceID})
1970 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001971 }
1972 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001973 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
1974 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001975 }
1976 return nil
1977}
1978
dbainbri4d3a0dc2020-12-02 00:33:42 +00001979func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001980 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001981 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001982 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
1983 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001984
mpagenko900ee4b2020-10-12 11:56:34 +00001985 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1986 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1987 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001988 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001989 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001990 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001991 // abort: system behavior is just unstable ...
1992 return err
1993 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001994 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001995 _ = 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 +00001996
1997 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00001998 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001999 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002000 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002001 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2002 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002003 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002004 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002005
2006 //TODO!!! remove existing traffic profiles
2007 /* from py code, if TP's exist, remove them - not yet implemented
2008 self._tp = dict()
2009 # Let TP download happen again
2010 for uni_id in self._tp_service_specific_task:
2011 self._tp_service_specific_task[uni_id].clear()
2012 for uni_id in self._tech_profile_download_done:
2013 self._tech_profile_download_done[uni_id].clear()
2014 */
2015
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002016 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002017
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002018 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002019
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002020 if err := dh.deviceReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002021 // abort: system behavior is just unstable ...
2022 return err
2023 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002024 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002025 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002026 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002027 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002028 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2029 OperStatus: voltha.OperStatus_DISCOVERED,
2030 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002031 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002032 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002033 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002034 // abort: system behavior is just unstable ...
2035 return err
2036 }
2037 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002038 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002039 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002040 return nil
2041}
2042
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002043func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002044 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2045 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2046 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2047 // and using the stop/reset event should never harm
2048
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002049 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002050 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002051 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2052 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00002053 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002054 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002055 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002056 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002057 pDevEntry.MutexOnuImageStatus.RLock()
2058 if pDevEntry.POnuImageStatus != nil {
2059 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002060 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002061 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002062
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002063 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002064 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002065 }
2066 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002067 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002068 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002069 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002070 }
2071 //port lock/unlock FSM's may be active
2072 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002073 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002074 }
2075 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002076 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002077 }
2078 //techProfile related PonAniConfigFsm FSM may be active
2079 if dh.pOnuTP != nil {
2080 // should always be the case here
2081 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002082 if dh.pOnuTP.PAniConfigFsm != nil {
2083 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2084 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002085 }
mpagenko900ee4b2020-10-12 11:56:34 +00002086 }
2087 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002088 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002089 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002090 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002091 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002092 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002093 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002094 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002095 } else {
2096 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002097 }
2098 }
2099 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002100 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002101 // Stop collector routine
2102 dh.stopCollector <- true
2103 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002104 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302105 dh.stopAlarmManager <- true
2106 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002107 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002108 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002109 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302110
Girish Gowdrae95687a2021-09-08 16:30:58 -07002111 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2112
mpagenko80622a52021-02-09 16:53:23 +00002113 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002114 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002115 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002116 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002117 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002118 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002119 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002120 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2121 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2122 // (even though it may also run into direct cancellation, a bit hard to verify here)
2123 // so don't set 'dh.upgradeCanceled = true' here!
2124 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2125 }
mpagenko38662d02021-08-11 09:45:19 +00002126 }
mpagenko80622a52021-02-09 16:53:23 +00002127
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002128 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002129 return nil
2130}
2131
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002132func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2133 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 +05302134
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002135 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002136 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002137 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002138 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002139 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002140 _ = dh.deviceReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling())
2141 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002142
mpagenkoa40e99a2020-11-17 13:50:39 +00002143 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2144 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2145 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2146 * disable/enable toggling here to allow traffic
2147 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2148 * like the py comment says:
2149 * # start by locking all the unis till mib sync and initial mib is downloaded
2150 * # this way we can capture the port down/up events when we are ready
2151 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302152
mpagenkoa40e99a2020-11-17 13:50:39 +00002153 // Init Uni Ports to Admin locked state
2154 // *** should generate UniLockStateDone event *****
2155 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002156 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002157 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002158 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002159 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002160 }
2161}
2162
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002163func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2164 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302165 /* Mib download procedure -
2166 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2167 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002168 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002169 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002170 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002171 return
2172 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002173 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302174 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002175 if pMibDlFsm.Is(mib.DlStDisabled) {
2176 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2177 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 +05302178 // maybe try a FSM reset and then again ... - TODO!!!
2179 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002180 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302181 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002182 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2183 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302184 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002185 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302186 //Begin MIB data download (running autonomously)
2187 }
2188 }
2189 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002190 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002191 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302192 // maybe try a FSM reset and then again ... - TODO!!!
2193 }
2194 /***** Mib download started */
2195 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002196 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302197 }
2198}
2199
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002200func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2201 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302202 //initiate DevStateUpdate
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002203 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002204 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002205 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002206 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2207 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2208 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2209 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002210 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002211 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002212 ConnStatus: voltha.ConnectStatus_REACHABLE,
2213 OperStatus: voltha.OperStatus_ACTIVE,
2214 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302215 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002216 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302217 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002218 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302219 }
2220 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002221 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002222 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302223 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002224 _ = dh.deviceReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002225
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002226 if !dh.GetCollectorIsRunning() {
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002227 // Start PM collector routine
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002228 go dh.StartCollector(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002229 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002230 if !dh.GetAlarmManagerIsRunning(ctx) {
2231 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002232 }
2233
Girish Gowdrae95687a2021-09-08 16:30:58 -07002234 // Start flow handler routines per UNI
2235 for _, uniPort := range dh.uniEntityMap {
2236 // only if this port was enabled for use by the operator at startup
2237 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2238 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2239 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2240 }
2241 }
2242 }
2243
Girish Gowdrae0140f02021-02-02 16:55:09 -08002244 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002245 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002246 // There is no way we should be landing here, but if we do then
2247 // there is nothing much we can do about this other than log error
2248 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2249 }
2250
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002251 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002252
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002253 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002254 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002255 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002256 return
2257 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002258 pDevEntry.MutexPersOnuConfig.RLock()
2259 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2260 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002261 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002262 log.Fields{"device-id": dh.DeviceID})
2263 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002264 // reconcilement will be continued after ani config is done
2265 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002266 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002267 // *** should generate UniUnlockStateDone event *****
2268 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002269 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002270 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002271 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002272 dh.runUniLockFsm(ctx, false)
2273 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302274 }
2275}
2276
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002277func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2278 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302279
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002280 if !dh.IsReconciling() {
2281 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002282 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002283 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2284 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002285 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002286 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002287 return
2288 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002289 pDevEntry.MutexPersOnuConfig.Lock()
2290 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2291 pDevEntry.MutexPersOnuConfig.Unlock()
2292 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002293 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002294 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002295 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302296 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002297 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 +00002298 log.Fields{"device-id": dh.DeviceID})
2299 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002300 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302301 }
2302}
2303
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002304func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002305 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002306 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002307
mpagenko44bd8362021-11-15 11:40:05 +00002308 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002309 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002310 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002311 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002312 OperStatus: voltha.OperStatus_UNKNOWN,
2313 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002314 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002315 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002316 }
2317
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002318 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002319 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002320 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002321
2322 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002323 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002324
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002325 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002326 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002327 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002328 return
2329 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002330 pDevEntry.MutexPersOnuConfig.Lock()
2331 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2332 pDevEntry.MutexPersOnuConfig.Unlock()
2333 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002334 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002335 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002336 }
mpagenko900ee4b2020-10-12 11:56:34 +00002337}
2338
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002339func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002340 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002341 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002342 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002343 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002344 ConnStatus: voltha.ConnectStatus_REACHABLE,
2345 OperStatus: voltha.OperStatus_ACTIVE,
2346 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002347 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002348 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002349 }
2350
dbainbri4d3a0dc2020-12-02 00:33:42 +00002351 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002352 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002353 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002354 _ = dh.deviceReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002355
2356 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002357 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002358
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002359 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002360 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002361 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002362 return
2363 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002364 pDevEntry.MutexPersOnuConfig.Lock()
2365 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2366 pDevEntry.MutexPersOnuConfig.Unlock()
2367 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002368 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002369 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002370 }
mpagenko900ee4b2020-10-12 11:56:34 +00002371}
2372
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002373func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2374 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2375 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002376 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002377 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002378 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002379 OperStatus: voltha.OperStatus_FAILED,
2380 }); err != nil {
2381 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2382 }
2383}
2384
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002385func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2386 if devEvent == cmn.OmciAniConfigDone {
2387 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002388 // attention: the device reason update is done based on ONU-UNI-Port related activity
2389 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002390 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002391 // which may be the case from some previous actvity even on this UNI Port (but also other UNI ports)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002392 _ = dh.deviceReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302393 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002394 if dh.IsReconciling() {
2395 go dh.ReconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002396 }
2397 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002398 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002399 // attention: the device reason update is done based on ONU-UNI-Port related activity
2400 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002401 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002402 // which may be the case from some previous actvity even on this ONU port (but also other UNI ports)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002403 _ = dh.deviceReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002404 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002405 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302406}
2407
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002408func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002409 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002410 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302411 // attention: the device reason update is done based on ONU-UNI-Port related activity
2412 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302413
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002414 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2415 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002416 // which may be the case from some previous actvity on another UNI Port of the ONU
2417 // or even some previous flow add activity on the same port
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002418 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling())
2419 if dh.IsReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002420 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002421 }
2422 }
2423 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002424 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002425 //not relevant for reconcile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002426 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002427 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302428 }
mpagenkof1fc3862021-02-16 10:09:52 +00002429
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002430 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002431 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002432 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002433 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002434 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002435 }
2436 } else {
2437 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002438 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002439 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302440}
2441
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002442//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
2443func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302444 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002445 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002446 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002447 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002448 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002449 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002450 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002451 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002452 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002453 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002454 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002455 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002456 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002457 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002458 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002459 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002460 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002461 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002462 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002463 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002464 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002465 case cmn.UniEnableStateFailed:
2466 {
2467 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2468 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002469 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002470 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002471 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002472 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002473 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002474 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002475 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002476 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002477 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002478 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002479 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002480 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002481 default:
2482 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002483 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002484 }
2485 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002486}
2487
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002488func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002489 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002490 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302491 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002492 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002493 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002494 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302495 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002496 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002497 if pUniPort == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002498 logger.Warnw(ctx, "OnuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002499 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002500 //store UniPort with the System-PortNumber key
2501 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002502 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002503 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002504 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
2505 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002506 } //error logging already within UniPort method
2507 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002508 logger.Debugw(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002509 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002510 }
2511 }
2512}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002513
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002514func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2515 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47: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 Hildebrandtbe523842021-03-10 10:47:18 +00002518 return
2519 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002520 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002521 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002522 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2523 for _, mgmtEntityID := range pptpInstKeys {
2524 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002525 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002526 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2527 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002528 }
2529 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002530 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002531 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002532 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002533 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2534 for _, mgmtEntityID := range veipInstKeys {
2535 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002536 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002537 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2538 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002539 }
2540 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002541 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002542 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002543 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002544 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2545 for _, mgmtEntityID := range potsInstKeys {
2546 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002547 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002548 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2549 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002550 }
2551 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002552 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002553 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002554 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002555 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002556 return
2557 }
2558
2559 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2560 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2561 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
2562 for i := 0; i < int(uniCnt); i++ {
2563 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
2564 dh.stopFlowMonitoringRoutine[i] = make(chan bool)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002565 }
2566}
2567
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002568// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2569func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002570 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302571 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002572 // with following remark:
2573 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2574 // # load on the core
2575
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002576 // 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 +00002577
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002578 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002579 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002580 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2581 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2582 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2583 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002584 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002585 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002586 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002587 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002588 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002589 PortNo: port.PortNo,
2590 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002591 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002592 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 -04002593 }
2594 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002595 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002596 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002597 }
mpagenko3af1f032020-06-10 08:53:41 +00002598 }
2599 }
2600}
2601
2602// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002603func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2604 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002605 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2606 for uniNo, uniPort := range dh.uniEntityMap {
2607 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002608
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002609 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2610 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2611 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2612 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002613 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002614 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002615 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002616 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002617 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002618 PortNo: port.PortNo,
2619 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002620 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002621 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 -04002622 }
2623 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002624 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002625 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002626 }
2627
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002628 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002629 }
2630}
2631
2632// ONU_Active/Inactive announcement on system KAFKA bus
2633// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002634func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002635 var de voltha.DeviceEvent
2636 eventContext := make(map[string]string)
2637 //Populating event context
2638 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002639 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002640 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002641 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302642 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002643 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 +00002644 }
2645 oltSerialNumber := parentDevice.SerialNumber
2646
2647 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2648 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2649 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302650 eventContext["olt-serial-number"] = oltSerialNumber
2651 eventContext["device-id"] = aDeviceID
2652 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002653 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002654 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2655 deviceEntry.MutexPersOnuConfig.RLock()
2656 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2657 deviceEntry.MutexPersOnuConfig.RUnlock()
2658 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
2659 deviceEntry.MutexPersOnuConfig.RLock()
2660 eventContext["vendor"] = deviceEntry.SOnuPersistentData.PersVendorID
2661 deviceEntry.MutexPersOnuConfig.RUnlock()
2662 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002663 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2664 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2665 } else {
2666 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2667 log.Fields{"device-id": aDeviceID})
2668 return
2669 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002670
2671 /* Populating device event body */
2672 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302673 de.ResourceId = aDeviceID
2674 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002675 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2676 de.Description = fmt.Sprintf("%s Event - %s - %s",
2677 cEventObjectType, cOnuActivatedEvent, "Raised")
2678 } else {
2679 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2680 de.Description = fmt.Sprintf("%s Event - %s - %s",
2681 cEventObjectType, cOnuActivatedEvent, "Cleared")
2682 }
2683 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002684 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2685 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302686 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002687 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002688 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302689 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002690}
2691
Himani Chawla4d908332020-08-31 12:30:20 +05302692// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002693func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2694 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002695 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302696 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002697 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002698 sFsmName = "LockStateFSM"
2699 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002700 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002701 sFsmName = "UnLockStateFSM"
2702 }
mpagenko3af1f032020-06-10 08:53:41 +00002703
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002704 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002705 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002706 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002707 return
2708 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002709 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002710 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302711 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002712 dh.pLockStateFsm = pLSFsm
2713 } else {
2714 dh.pUnlockStateFsm = pLSFsm
2715 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002716 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002717 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002718 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002719 }
2720}
2721
2722// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002723func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002724 /* Uni Port lock/unlock procedure -
2725 ***** should run via 'adminDone' state and generate the argument requested event *****
2726 */
2727 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302728 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002729 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002730 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2731 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002732 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2733 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002734 }
2735 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002736 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002737 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2738 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002739 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2740 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002741 }
2742 }
2743 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002744 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2745 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002746 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002747 // maybe try a FSM reset and then again ... - TODO!!!
2748 } else {
2749 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002750 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002751 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002752 }
2753 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002754 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002755 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002756 // maybe try a FSM reset and then again ... - TODO!!!
2757 }
2758 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002759 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002760 // maybe try a FSM reset and then again ... - TODO!!!
2761 }
2762}
2763
mpagenko80622a52021-02-09 16:53:23 +00002764// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00002765// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002766func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002767 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002768 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002769 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002770 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002771 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002772 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002773 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002774 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002775 sFsmName, chUpgradeFsm)
2776 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002777 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00002778 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002779 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
2780 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
mpagenko80622a52021-02-09 16:53:23 +00002781 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2782 // maybe try a FSM reset and then again ... - TODO!!!
2783 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2784 }
mpagenko59862f02021-10-11 08:53:18 +00002785 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00002786 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2787 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00002788 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2789 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002790 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002791 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002792 } else {
2793 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002794 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002795 // maybe try a FSM reset and then again ... - TODO!!!
2796 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2797 }
2798 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002799 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002800 // maybe try a FSM reset and then again ... - TODO!!!
2801 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2802 }
2803 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002804 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002805 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2806 }
2807 return nil
2808}
2809
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002810// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
2811func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002812 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002813 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002814 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00002815 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2816 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00002817 dh.pLastUpgradeImageState = apImageState
2818 dh.lockUpgradeFsm.Unlock()
2819 //signal upgradeFsm removed using non-blocking channel send
2820 select {
2821 case dh.upgradeFsmChan <- struct{}{}:
2822 default:
2823 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002824 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00002825 }
mpagenko80622a52021-02-09 16:53:23 +00002826}
2827
mpagenko15ff4a52021-03-02 10:09:20 +00002828// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2829func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002830 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00002831 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002832 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002833 return
2834 }
2835
2836 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00002837 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00002838 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002839 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
2840 dh.lockUpgradeFsm.RUnlock()
2841 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
2842 return
2843 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002844 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00002845 if pUpgradeStatemachine != nil {
2846 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2847 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002848 UpgradeState := pUpgradeStatemachine.Current()
2849 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
2850 (UpgradeState == swupg.UpgradeStRequestingActivate) {
2851 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00002852 // 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 +00002853 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00002854 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
2855 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00002856 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00002857 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002858 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00002859 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2860 dh.upgradeCanceled = true
2861 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2862 }
mpagenko15ff4a52021-03-02 10:09:20 +00002863 return
2864 }
mpagenko59862f02021-10-11 08:53:18 +00002865 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002866 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
2867 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00002868 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002869 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
mpagenko1f8e8822021-06-25 14:10:21 +00002870 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
2871 return
2872 }
2873 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002874 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00002875 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002876 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
2877 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
mpagenko1f8e8822021-06-25 14:10:21 +00002878 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2879 return
2880 }
2881 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002882 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00002883 }
2884 } else {
2885 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 +00002886 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00002887 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2888 dh.upgradeCanceled = true
2889 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2890 }
mpagenko1f8e8822021-06-25 14:10:21 +00002891 }
mpagenko15ff4a52021-03-02 10:09:20 +00002892 return
2893 }
mpagenko59862f02021-10-11 08:53:18 +00002894 dh.lockUpgradeFsm.RUnlock()
2895 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2896 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00002897 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2898 dh.upgradeCanceled = true
2899 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2900 }
mpagenko59862f02021-10-11 08:53:18 +00002901 return
2902 }
2903 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2904 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2905 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2906 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
2907 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2908 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
2909 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00002910 }
mpagenko15ff4a52021-03-02 10:09:20 +00002911 }
2912 }
2913 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002914 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002915 }
mpagenko59862f02021-10-11 08:53:18 +00002916 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00002917}
2918
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002919//SetBackend provides a DB backend for the specified path on the existing KV client
2920func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002921
2922 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002923 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07002924 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00002925 kvbackend := &db.Backend{
2926 Client: dh.pOpenOnuAc.kvClient,
2927 StoreType: dh.pOpenOnuAc.KVStoreType,
2928 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002929 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002930 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2931 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002932
mpagenkoaf801632020-07-03 10:00:42 +00002933 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002934}
khenaidoo7d3c5582021-08-11 18:09:44 -04002935func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302936 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002937
mpagenkodff5dda2020-08-28 11:52:01 +00002938 for _, field := range flow.GetOfbFields(apFlowItem) {
2939 switch field.Type {
2940 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2941 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002942 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002943 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2944 }
mpagenko01e726e2020-10-23 09:45:29 +00002945 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002946 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2947 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302948 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002949 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302950 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2951 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002952 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2953 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002954 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002955 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302956 return
mpagenkodff5dda2020-08-28 11:52:01 +00002957 }
2958 }
mpagenko01e726e2020-10-23 09:45:29 +00002959 */
mpagenkodff5dda2020-08-28 11:52:01 +00002960 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2961 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302962 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002963 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302964 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002965 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302966 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002967 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002968 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302969 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002970 }
2971 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2972 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302973 *loAddPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002974 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002975 "PCP": loAddPcp})
2976 }
2977 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2978 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002979 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002980 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2981 }
2982 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2983 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002984 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002985 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2986 }
2987 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2988 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002989 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002990 "IPv4-DST": field.GetIpv4Dst()})
2991 }
2992 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2993 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002994 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002995 "IPv4-SRC": field.GetIpv4Src()})
2996 }
2997 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2998 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002999 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003000 "Metadata": field.GetTableMetadata()})
3001 }
3002 /*
3003 default:
3004 {
3005 //all other entires ignored
3006 }
3007 */
3008 }
3009 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303010}
mpagenkodff5dda2020-08-28 11:52:01 +00003011
khenaidoo7d3c5582021-08-11 18:09:44 -04003012func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003013 for _, action := range flow.GetActions(apFlowItem) {
3014 switch action.Type {
3015 /* not used:
3016 case of.OfpActionType_OFPAT_OUTPUT:
3017 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003018 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003019 "Output": action.GetOutput()})
3020 }
3021 */
3022 case of.OfpActionType_OFPAT_PUSH_VLAN:
3023 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003024 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003025 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3026 }
3027 case of.OfpActionType_OFPAT_SET_FIELD:
3028 {
3029 pActionSetField := action.GetSetField()
3030 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003031 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003032 "OxcmClass": pActionSetField.Field.OxmClass})
3033 }
3034 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303035 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003036 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303037 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003038 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303039 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003040 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303041 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003042 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003043 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003044 "Type": pActionSetField.Field.GetOfbField().Type})
3045 }
3046 }
3047 /*
3048 default:
3049 {
3050 //all other entires ignored
3051 }
3052 */
3053 }
3054 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303055}
3056
3057//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003058func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003059 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303060 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3061 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
3062 var loAddPcp, loSetPcp uint8
3063 var loIPProto uint32
3064 /* the TechProfileId is part of the flow Metadata - compare also comment within
3065 * OLT-Adapter:openolt_flowmgr.go
3066 * Metadata 8 bytes:
3067 * Most Significant 2 Bytes = Inner VLAN
3068 * Next 2 Bytes = Tech Profile ID(TPID)
3069 * Least Significant 4 Bytes = Port ID
3070 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3071 * subscriber related flows.
3072 */
3073
dbainbri4d3a0dc2020-12-02 00:33:42 +00003074 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303075 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003076 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003077 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003078 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303079 }
mpagenko551a4d42020-12-08 18:09:20 +00003080 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003081 loCookie := apFlowItem.GetCookie()
3082 loCookieSlice := []uint64{loCookie}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003083 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003084 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05303085
dbainbri4d3a0dc2020-12-02 00:33:42 +00003086 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003087 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303088 if loIPProto == 2 {
3089 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3090 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003091 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003092 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303093 return nil
3094 }
mpagenko01e726e2020-10-23 09:45:29 +00003095 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003096 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003097
3098 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003099 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003100 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003101 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3102 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3103 //TODO!!: Use DeviceId within the error response to rwCore
3104 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003105 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003106 }
3107 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003108 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003109 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3110 } else {
3111 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3112 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3113 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303114 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003115 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003116 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003117 }
mpagenko9a304ea2020-12-16 15:54:01 +00003118
khenaidoo42dcdfd2021-10-19 17:34:12 -04003119 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003120 if apFlowMetaData != nil {
3121 meter = apFlowMetaData.Meters[0]
3122 }
mpagenkobc4170a2021-08-17 16:42:10 +00003123 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3124 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3125 // when different rules are requested concurrently for the same uni
3126 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3127 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3128 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003129 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3130 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003131 //SetUniFlowParams() may block on some rule that is suspended-to-add
3132 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003133 // Also the error is returned to caller via response channel
3134 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
3135 loMatchVlan, loSetVlan, loSetPcp, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003136 dh.lockVlanConfig.RUnlock()
3137 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003138 return
mpagenkodff5dda2020-08-28 11:52:01 +00003139 }
mpagenkobc4170a2021-08-17 16:42:10 +00003140 dh.lockVlanConfig.RUnlock()
3141 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003142 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003143 loMatchVlan, loSetVlan, loSetPcp, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003144 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003145 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003146 if err != nil {
3147 *respChan <- err
3148 }
mpagenko01e726e2020-10-23 09:45:29 +00003149}
3150
3151//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003152func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003153 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3154 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3155 //no extra check is done on the rule parameters
3156 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3157 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3158 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3159 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003160 // - 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 +00003161 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003162 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003163
3164 /* TT related temporary workaround - should not be needed anymore
3165 for _, field := range flow.GetOfbFields(apFlowItem) {
3166 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3167 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003168 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003169 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3170 if loIPProto == 2 {
3171 // 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 +00003172 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003173 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003174 return nil
3175 }
3176 }
3177 } //for all OfbFields
3178 */
3179
mpagenko9a304ea2020-12-16 15:54:01 +00003180 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003181 dh.lockVlanConfig.RLock()
3182 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003183 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3184 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003185 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3186 return
mpagenko01e726e2020-10-23 09:45:29 +00003187 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003188 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003189 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003190 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003191 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003192 // Push response on the response channel
3193 if respChan != nil {
3194 // 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
3195 select {
3196 case *respChan <- nil:
3197 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3198 default:
3199 }
3200 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003201 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003202}
3203
Himani Chawla26e555c2020-08-31 12:30:20 +05303204// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003205// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003206// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003207func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003208 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 +00003209 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003210
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003211 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003212 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003213 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3214 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003215 }
3216
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003217 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3218 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003219 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003220 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003221 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3222 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003223 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3224 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003225 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003226 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3227 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003228 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003229 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003230 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303231 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003232 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003233 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3234 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003235 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003236 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003237 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3238 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003239 }
3240 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003241 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003242 "device-id": dh.DeviceID})
3243 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003244 }
3245 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003246 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003247 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3248 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003249 }
3250 return nil
3251}
3252
mpagenkofc4f56e2020-11-04 17:17:49 +00003253//VerifyVlanConfigRequest checks on existence of a given uniPort
3254// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003255func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003256 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003257 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003258 for _, uniPort := range dh.uniEntityMap {
3259 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003260 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003261 pCurrentUniPort = uniPort
3262 break //found - end search loop
3263 }
3264 }
3265 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003266 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003267 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003268 return
3269 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003270 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003271}
3272
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003273//VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
3274func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003275 //TODO!! verify and start pending flow configuration
3276 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3277 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003278
3279 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003280 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003281 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003282 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003283 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003284 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003285 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003286 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003287 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3288 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003289 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003290 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003291 } else {
3292 /***** UniVlanConfigFsm continued */
3293 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003294 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3295 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003296 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003297 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3298 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003299 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003300 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003301 } else {
3302 /***** UniVlanConfigFsm continued */
3303 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003304 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3305 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003306 }
mpagenkodff5dda2020-08-28 11:52:01 +00003307 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003308 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003309 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3310 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003311 }
3312 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003313 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 +00003314 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3315 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003316 }
3317 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003318 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003319 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003320 }
mpagenkof1fc3862021-02-16 10:09:52 +00003321 } else {
3322 dh.lockVlanConfig.RUnlock()
3323 }
mpagenkodff5dda2020-08-28 11:52:01 +00003324}
3325
3326//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3327// 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 +00003328func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003329 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003330 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003331 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003332 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003333 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003334 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003335}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003336
mpagenkof1fc3862021-02-16 10:09:52 +00003337//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003338func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003339 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3340 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3341 // obviously then parallel processing on the cancel must be avoided
3342 // deadline context to ensure completion of background routines waited for
3343 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3344 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3345 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3346
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003347 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003348 var wg sync.WaitGroup
3349 wg.Add(1) // for the 1 go routine to finish
3350
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003351 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003352 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3353
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003354 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003355}
3356
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003357//StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003358//available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003359func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3360 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003361
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003362 if dh.IsReconciling() {
3363 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003364 return nil
3365 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003366 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003367
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003368 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003369 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003370 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3371 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003372 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003373 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003374
mpagenkof1fc3862021-02-16 10:09:52 +00003375 if aWriteToKvStore {
3376 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3377 }
3378 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003379}
3380
dbainbri4d3a0dc2020-12-02 00:33:42 +00003381func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003382 defer cancel() //ensure termination of context (may be pro forma)
3383 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003384 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003385 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003386}
3387
dbainbri4d3a0dc2020-12-02 00:33:42 +00003388func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003389
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003390 dh.SetDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003391 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003392 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003393 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003394 DeviceId: dh.DeviceID,
3395 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003396 }); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003397 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003398 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003399 return err
3400 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003401 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", cmn.DeviceReasonMap[deviceReason], dh.DeviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003402 return nil
3403 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003404 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", cmn.DeviceReasonMap[deviceReason], dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003405 return nil
3406}
3407
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003408func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3409 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003410 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003411 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3412 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003413 }
mpagenkof1fc3862021-02-16 10:09:52 +00003414 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003415}
3416
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003417// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003418// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003419func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3420 dh.lockDevice.RLock()
3421 defer dh.lockDevice.RUnlock()
3422 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003423 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003424 }
3425 return 0, errors.New("error-fetching-uni-port")
3426}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003427
3428// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003429func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3430 var errorsList []error
3431 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 -08003432
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003433 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3434 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3435 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3436
3437 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3438 // successfully.
3439 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3440 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3441 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003442 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 -08003443 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003444 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003445 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003446 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003447}
3448
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003449func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3450 var err error
3451 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003452 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003453
3454 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003455 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003456 errorsList = append(errorsList, err)
3457 }
3458 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003459 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003460
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003461 return errorsList
3462}
3463
3464func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3465 var err error
3466 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003467 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003468 // Check if group metric related config is updated
3469 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003470 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3471 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3472 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003473
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003474 if ok && m.Frequency != v.GroupFreq {
3475 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003476 errorsList = append(errorsList, err)
3477 }
3478 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003479 if ok && m.Enabled != v.Enabled {
3480 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003481 errorsList = append(errorsList, err)
3482 }
3483 }
3484 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003485 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003486 return errorsList
3487}
3488
3489func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3490 var err error
3491 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003492 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003493 // Check if standalone metric related config is updated
3494 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003495 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3496 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3497 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003498
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003499 if ok && m.Frequency != v.SampleFreq {
3500 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003501 errorsList = append(errorsList, err)
3502 }
3503 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003504 if ok && m.Enabled != v.Enabled {
3505 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003506 errorsList = append(errorsList, err)
3507 }
3508 }
3509 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003510 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003511 return errorsList
3512}
3513
3514// nolint: gocyclo
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003515func (dh *deviceHandler) StartCollector(ctx context.Context) {
Girish Gowdrae09a6202021-01-12 18:10:59 -08003516 logger.Debugf(ctx, "startingCollector")
3517
3518 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003519 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303520 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003521 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003522 // Initialize the next metric collection time.
3523 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3524 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003525 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003526 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003527 for {
3528 select {
3529 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003530 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003531 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003532 // Stop the L2 PM FSM
3533 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003534 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3535 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3536 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003537 }
3538 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003539 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003540 }
3541 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003542 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3543 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003544 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003545 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3546 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003547 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003548
Girish Gowdrae09a6202021-01-12 18:10:59 -08003549 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003550 case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3551 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3552 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3553 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3554 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003555 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003556 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003557 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003558 } else {
3559 if dh.pmConfigs.Grouped { // metrics are managed as a group
3560 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003561 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003562
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003563 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3564 // 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 -08003565 // 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 +00003566 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3567 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003568 }
3569 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003570 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3571 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3572 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3573 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003574 }
3575 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003576 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003577
3578 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003579 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3580 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3581 // 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 -08003582 // 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 +00003583 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3584 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003585 }
3586 }
3587 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003588 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3589 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3590 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3591 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003592 }
3593 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003594 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003595 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003596 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003597 } */
3598 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003599 }
3600 }
3601}
kesavandfdf77632021-01-26 23:40:33 -05003602
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003603func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003604
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003605 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3606 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003607}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003608
Himani Chawla43f95ff2021-06-03 00:24:12 +05303609func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3610 if dh.pOnuMetricsMgr == nil {
3611 return &extension.SingleGetValueResponse{
3612 Response: &extension.GetValueResponse{
3613 Status: extension.GetValueResponse_ERROR,
3614 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3615 },
3616 }
3617 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303618 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303619 return resp
3620}
3621
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003622func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3623 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003624 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003625 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003626 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003627}
3628
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003629func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003630 var pAdapterFsm *cmn.AdapterFsm
3631 //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 +00003632 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003633 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003634 {
mpagenkofbf577d2021-10-12 11:44:33 +00003635 if dh.pOnuOmciDevice != nil {
3636 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3637 } else {
3638 return true //FSM not active - so there is no activity on omci
3639 }
mpagenkof1fc3862021-02-16 10:09:52 +00003640 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003641 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003642 {
mpagenkofbf577d2021-10-12 11:44:33 +00003643 if dh.pOnuOmciDevice != nil {
3644 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3645 } else {
3646 return true //FSM not active - so there is no activity on omci
3647 }
mpagenkof1fc3862021-02-16 10:09:52 +00003648 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003649 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003650 {
mpagenkofbf577d2021-10-12 11:44:33 +00003651 if dh.pLockStateFsm != nil {
3652 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3653 } else {
3654 return true //FSM not active - so there is no activity on omci
3655 }
mpagenkof1fc3862021-02-16 10:09:52 +00003656 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003657 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003658 {
mpagenkofbf577d2021-10-12 11:44:33 +00003659 if dh.pUnlockStateFsm != nil {
3660 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3661 } else {
3662 return true //FSM not active - so there is no activity on omci
3663 }
mpagenkof1fc3862021-02-16 10:09:52 +00003664 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003665 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003666 {
mpagenkofbf577d2021-10-12 11:44:33 +00003667 if dh.pOnuMetricsMgr != nil {
3668 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003669 } else {
3670 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003671 }
3672 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003673 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003674 {
3675 dh.lockUpgradeFsm.RLock()
3676 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003677 if dh.pOnuUpradeFsm != nil {
3678 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3679 } else {
3680 return true //FSM not active - so there is no activity on omci
3681 }
mpagenko80622a52021-02-09 16:53:23 +00003682 }
mpagenkof1fc3862021-02-16 10:09:52 +00003683 default:
3684 {
3685 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003686 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003687 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003688 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003689 }
mpagenkofbf577d2021-10-12 11:44:33 +00003690 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3691 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3692 }
3693 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003694}
3695
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003696func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3697 for _, v := range dh.pOnuTP.PAniConfigFsm {
3698 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003699 return false
3700 }
3701 }
3702 return true
3703}
3704
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003705func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003706 dh.lockVlanConfig.RLock()
3707 defer dh.lockVlanConfig.RUnlock()
3708 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003709 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003710 return false
3711 }
3712 }
3713 return true //FSM not active - so there is no activity on omci
3714}
3715
3716func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3717 dh.lockVlanConfig.RLock()
3718 defer dh.lockVlanConfig.RUnlock()
3719 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003720 if v.PAdaptFsm.PFsm != nil {
3721 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003722 return true //there is at least one VLAN FSM with some active configuration
3723 }
3724 }
3725 }
3726 return false //there is no VLAN FSM with some active configuration
3727}
3728
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003729func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003730 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3731 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3732 return false
3733 }
3734 }
3735 // a further check is done to identify, if at least some data traffic related configuration exists
3736 // 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])
3737 return dh.checkUserServiceExists(ctx)
3738}
3739
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003740func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003741 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3742 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003743 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003744 // TODO: fatal error reset ONU, delete deviceHandler!
3745 return
3746 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003747 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
3748 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003749}
3750
3751func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3752 dh.mutexCollectorFlag.Lock()
3753 dh.collectorIsRunning = flagValue
3754 dh.mutexCollectorFlag.Unlock()
3755}
3756
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003757func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003758 dh.mutexCollectorFlag.RLock()
3759 flagValue := dh.collectorIsRunning
3760 dh.mutexCollectorFlag.RUnlock()
3761 return flagValue
3762}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303763
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303764func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3765 dh.mutextAlarmManagerFlag.Lock()
3766 dh.alarmManagerIsRunning = flagValue
3767 dh.mutextAlarmManagerFlag.Unlock()
3768}
3769
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003770func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303771 dh.mutextAlarmManagerFlag.RLock()
3772 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303773 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303774 dh.mutextAlarmManagerFlag.RUnlock()
3775 return flagValue
3776}
3777
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003778func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303779 logger.Debugf(ctx, "startingAlarmManager")
3780
3781 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003782 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303783 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303784 if stop := <-dh.stopAlarmManager; stop {
3785 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303786 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303787 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003788 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
3789 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05303790 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303791 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003792 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
3793 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05303794 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303795 }
3796}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003797
Girish Gowdrae95687a2021-09-08 16:30:58 -07003798func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
3799 dh.mutexFlowMonitoringRoutineFlag.Lock()
3800 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
3801 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"flag": flag})
3802 dh.isFlowMonitoringRoutineActive[uniID] = flag
3803}
3804
3805func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
3806 dh.mutexFlowMonitoringRoutineFlag.RLock()
3807 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
3808 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
3809 log.Fields{"isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
3810 return dh.isFlowMonitoringRoutineActive[uniID]
3811}
3812
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003813func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
3814 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003815
Maninder7961d722021-06-16 22:10:28 +05303816 connectStatus := voltha.ConnectStatus_UNREACHABLE
3817 operState := voltha.OperStatus_UNKNOWN
3818
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003819 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003820 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003821 logger.Debugw(ctx, "wait for channel signal or timeout",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003822 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003823 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003824 case success := <-dh.chReconcilingFinished:
3825 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003826 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05303827 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003828 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05303829 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003830 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05303831 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003832 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
3833 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05303834 operState = voltha.OperStatus_ACTIVE
3835 } else {
3836 operState = voltha.OperStatus_ACTIVATING
3837 }
3838 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003839 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
3840 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
3841 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05303842 operState = voltha.OperStatus_DISCOVERED
3843 }
3844
3845 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303846 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003847 logger.Debugw(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003848 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04003849 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003850 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003851 ConnStatus: connectStatus,
3852 OperStatus: operState,
3853 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05303854 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003855 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05303856 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003857 } else {
Maninderb5187552021-03-23 22:23:42 +05303858 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003859 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05303860
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003861 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05303862 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003863 log.Fields{"device-id": dh.DeviceID})
3864 } else if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninder7961d722021-06-16 22:10:28 +05303865 connectStatus = voltha.ConnectStatus_REACHABLE
3866 }
3867
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003868 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003869 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003870 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003871 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003872 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05303873
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003874 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05303875 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003876 log.Fields{"device-id": dh.DeviceID})
3877 } else if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninder7961d722021-06-16 22:10:28 +05303878 connectStatus = voltha.ConnectStatus_REACHABLE
3879 }
3880
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003881 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05303882
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003883 }
3884 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003885 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003886 dh.mutexReconcilingFlag.Unlock()
3887 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003888 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003889 dh.mutexReconcilingFlag.Lock()
3890 if skipOnuConfig {
3891 dh.reconciling = cSkipOnuConfigReconciling
3892 } else {
3893 dh.reconciling = cOnuConfigReconciling
3894 }
3895 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003896}
3897
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003898func (dh *deviceHandler) StopReconciling(ctx context.Context, success bool) {
3899 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
3900 if dh.IsReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07003901 dh.chReconcilingFinished <- success
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003902 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003903 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003904 }
3905}
3906
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003907func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003908 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003909 defer dh.mutexReconcilingFlag.RUnlock()
3910 return dh.reconciling != cNoReconciling
3911}
3912
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003913func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003914 dh.mutexReconcilingFlag.RLock()
3915 defer dh.mutexReconcilingFlag.RUnlock()
3916 return dh.reconciling == cSkipOnuConfigReconciling
3917}
3918
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003919func (dh *deviceHandler) SetDeviceReason(value uint8) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003920 dh.mutexDeviceReason.Lock()
3921 dh.deviceReason = value
3922 dh.mutexDeviceReason.Unlock()
3923}
3924
3925func (dh *deviceHandler) getDeviceReason() uint8 {
3926 dh.mutexDeviceReason.RLock()
3927 value := dh.deviceReason
3928 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003929 return value
3930}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003931
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003932func (dh *deviceHandler) GetDeviceReasonString() string {
3933 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003934}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003935
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003936func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003937 dh.mutexReadyForOmciConfig.Lock()
3938 dh.readyForOmciConfig = flagValue
3939 dh.mutexReadyForOmciConfig.Unlock()
3940}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003941func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003942 dh.mutexReadyForOmciConfig.RLock()
3943 flagValue := dh.readyForOmciConfig
3944 dh.mutexReadyForOmciConfig.RUnlock()
3945 return flagValue
3946}
Maninder7961d722021-06-16 22:10:28 +05303947
3948func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
3949 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
3950 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003951 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05303952 }
3953
3954 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04003955 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003956 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003957 ConnStatus: connectStatus,
3958 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
3959 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05303960 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003961 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05303962 }
3963}
khenaidoo7d3c5582021-08-11 18:09:44 -04003964
3965/*
3966Helper functions to communicate with Core
3967*/
3968
3969func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
3970 cClient, err := dh.coreClient.GetCoreServiceClient()
3971 if err != nil || cClient == nil {
3972 return nil, err
3973 }
3974 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3975 defer cancel()
3976 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
3977 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
3978}
3979
khenaidoo42dcdfd2021-10-19 17:34:12 -04003980func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04003981 cClient, err := dh.coreClient.GetCoreServiceClient()
3982 if err != nil || cClient == nil {
3983 return err
3984 }
3985 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3986 defer cancel()
3987 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
3988 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-state": deviceStateFilter, "error": err})
3989 return err
3990}
3991
3992func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3993 cClient, err := dh.coreClient.GetCoreServiceClient()
3994 if err != nil || cClient == nil {
3995 return err
3996 }
3997 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3998 defer cancel()
3999 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
4000 logger.Debugw(subCtx, "pmconfig-updated-in-core", log.Fields{"pm-configs": pmConfigs, "error": err})
4001 return err
4002}
4003
4004func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4005 cClient, err := dh.coreClient.GetCoreServiceClient()
4006 if err != nil || cClient == nil {
4007 return err
4008 }
4009 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4010 defer cancel()
4011 _, err = cClient.DeviceUpdate(subCtx, device)
4012 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4013 return err
4014}
4015
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004016func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004017 cClient, err := dh.coreClient.GetCoreServiceClient()
4018 if err != nil || cClient == nil {
4019 return err
4020 }
4021 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4022 defer cancel()
4023 _, err = cClient.PortCreated(subCtx, port)
4024 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4025 return err
4026}
4027
khenaidoo42dcdfd2021-10-19 17:34:12 -04004028func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004029 cClient, err := dh.coreClient.GetCoreServiceClient()
4030 if err != nil || cClient == nil {
4031 return err
4032 }
4033 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4034 defer cancel()
4035 _, err = cClient.PortStateUpdate(subCtx, portState)
4036 logger.Debugw(subCtx, "port-state-updated-in-core", log.Fields{"port-state": portState, "error": err})
4037 return err
4038}
4039
khenaidoo42dcdfd2021-10-19 17:34:12 -04004040func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004041 cClient, err := dh.coreClient.GetCoreServiceClient()
4042 if err != nil || cClient == nil {
4043 return err
4044 }
4045 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4046 defer cancel()
4047 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
4048 logger.Debugw(subCtx, "device-reason-updated-in-core", log.Fields{"reason": reason, "error": err})
4049 return err
4050}
4051
4052/*
4053Helper functions to communicate with parent adapter
4054*/
4055
4056func (dh *deviceHandler) getTechProfileInstanceFromParentAdapter(ctx context.Context, parentEndpoint string,
khenaidoo42dcdfd2021-10-19 17:34:12 -04004057 request *ia.TechProfileInstanceRequestMessage) (*ia.TechProfileDownloadMessage, error) {
khenaidoo7d3c5582021-08-11 18:09:44 -04004058 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4059 if err != nil || pgClient == nil {
4060 return nil, err
4061 }
4062 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4063 defer cancel()
4064 logger.Debugw(subCtx, "get-tech-profile-instance", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4065 return pgClient.GetTechProfileInstance(subCtx, request)
4066}
4067
Girish Gowdrae95687a2021-09-08 16:30:58 -07004068// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4069// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4070func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4071 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4072 dh.setFlowMonitoringIsRunning(uniID, true)
4073 for {
4074 select {
4075 // block on the channel to receive an incoming flow
4076 // process the flow completely before proceeding to handle the next flow
4077 case flowCb := <-dh.flowCbChan[uniID]:
4078 startTime := time.Now()
4079 logger.Debugw(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
4080 respChan := make(chan error)
4081 if flowCb.addFlow {
4082 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4083 } else {
4084 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4085 }
4086 // Block on response and tunnel it back to the caller
4087 *flowCb.respChan <- <-respChan
4088 logger.Debugw(flowCb.ctx, "serial-flow-processor--end",
4089 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4090 case <-dh.stopFlowMonitoringRoutine[uniID]:
4091 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4092 dh.setFlowMonitoringIsRunning(uniID, false)
4093 return
4094 }
4095 }
4096}
4097
khenaidoo42dcdfd2021-10-19 17:34:12 -04004098func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004099 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4100 if err != nil || pgClient == nil {
4101 return err
4102 }
4103 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4104 defer cancel()
4105 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4106 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4107 if err != nil {
4108 logger.Errorw(ctx, "omci-failure", log.Fields{"request": request, "error": err, "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
4109 }
4110 return err
4111}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004112
4113// GetDeviceID - TODO: add comment
4114func (dh *deviceHandler) GetDeviceID() string {
4115 return dh.DeviceID
4116}
4117
4118// GetProxyAddressID - TODO: add comment
4119func (dh *deviceHandler) GetProxyAddressID() string {
4120 return dh.device.ProxyAddress.GetDeviceId()
4121}
4122
4123// GetProxyAddressType - TODO: add comment
4124func (dh *deviceHandler) GetProxyAddressType() string {
4125 return dh.device.ProxyAddress.GetDeviceType()
4126}
4127
4128// GetProxyAddress - TODO: add comment
4129func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4130 return dh.device.ProxyAddress
4131}
4132
4133// GetEventProxy - TODO: add comment
4134func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4135 return dh.EventProxy
4136}
4137
4138// GetOmciTimeout - TODO: add comment
4139func (dh *deviceHandler) GetOmciTimeout() int {
4140 return dh.pOpenOnuAc.omciTimeout
4141}
4142
4143// GetAlarmAuditInterval - TODO: add comment
4144func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4145 return dh.pOpenOnuAc.alarmAuditInterval
4146}
4147
4148// GetDlToOnuTimeout4M - TODO: add comment
4149func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4150 return dh.pOpenOnuAc.dlToOnuTimeout4M
4151}
4152
4153// GetUniEntityMap - TODO: add comment
4154func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4155 return &dh.uniEntityMap
4156}
4157
4158// GetPonPortNumber - TODO: add comment
4159func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4160 return &dh.ponPortNumber
4161}
4162
4163// GetUniVlanConfigFsm - TODO: add comment
4164func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004165 dh.lockVlanConfig.RLock()
4166 value := dh.UniVlanConfigFsmMap[uniID]
4167 dh.lockVlanConfig.RUnlock()
4168 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004169}
4170
4171// GetOnuAlarmManager - TODO: add comment
4172func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4173 return dh.pAlarmMgr
4174}
4175
4176// GetOnuMetricsManager - TODO: add comment
4177func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4178 return dh.pOnuMetricsMgr
4179}
4180
4181// GetOnuTP - TODO: add comment
4182func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4183 return dh.pOnuTP
4184}
4185
4186// GetBackendPathPrefix - TODO: add comment
4187func (dh *deviceHandler) GetBackendPathPrefix() string {
4188 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4189}
4190
4191// GetOnuIndication - TODO: add comment
4192func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4193 return dh.pOnuIndication
4194}
4195
4196// RLockMutexDeletionInProgressFlag - TODO: add comment
4197func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4198 dh.mutexDeletionInProgressFlag.RLock()
4199}
4200
4201// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4202func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4203 dh.mutexDeletionInProgressFlag.RUnlock()
4204}
4205
4206// GetDeletionInProgress - TODO: add comment
4207func (dh *deviceHandler) GetDeletionInProgress() bool {
4208 return dh.deletionInProgress
4209}
4210
4211// GetPmConfigs - TODO: add comment
4212func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4213 return dh.pmConfigs
4214}
4215
4216// GetDeviceType - TODO: add comment
4217func (dh *deviceHandler) GetDeviceType() string {
4218 return dh.DeviceType
4219}
4220
4221// GetLogicalDeviceID - TODO: add comment
4222func (dh *deviceHandler) GetLogicalDeviceID() string {
4223 return dh.logicalDeviceID
4224}
4225
4226// GetDevice - TODO: add comment
4227func (dh *deviceHandler) GetDevice() *voltha.Device {
4228 return dh.device
4229}
4230
4231// GetMetricsEnabled - TODO: add comment
4232func (dh *deviceHandler) GetMetricsEnabled() bool {
4233 return dh.pOpenOnuAc.MetricsEnabled
4234}
4235
4236// InitPmConfigs - TODO: add comment
4237func (dh *deviceHandler) InitPmConfigs() {
4238 dh.pmConfigs = &voltha.PmConfigs{}
4239}
4240
4241// GetUniPortMask - TODO: add comment
4242func (dh *deviceHandler) GetUniPortMask() int {
4243 return dh.pOpenOnuAc.config.UniPortMask
4244}