blob: f875553b8f3f83cef730dac6d4cba5258d1866e9 [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"
48 "github.com/opencord/voltha-protos/v5/go/extension"
49 ic "github.com/opencord/voltha-protos/v5/go/inter_container"
50 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
mpagenko59862f02021-10-11 08:53:18 +000051 "github.com/opencord/voltha-protos/v5/go/openolt"
khenaidoo7d3c5582021-08-11 18:09:44 -040052 oop "github.com/opencord/voltha-protos/v5/go/openolt"
mpagenko59862f02021-10-11 08:53:18 +000053 "github.com/opencord/voltha-protos/v5/go/tech_profile"
khenaidoo7d3c5582021-08-11 18:09:44 -040054 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000055)
56
mpagenko38662d02021-08-11 09:45:19 +000057// Constants for timeouts
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000058const (
mpagenko38662d02021-08-11 09:45:19 +000059 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000060)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000061
mpagenko1cc3cb42020-07-27 15:24:38 +000062const (
63 // events of Device FSM
64 devEvDeviceInit = "devEvDeviceInit"
65 devEvGrpcConnected = "devEvGrpcConnected"
66 devEvGrpcDisconnected = "devEvGrpcDisconnected"
67 devEvDeviceUpInd = "devEvDeviceUpInd"
68 devEvDeviceDownInd = "devEvDeviceDownInd"
69)
70const (
71 // states of Device FSM
72 devStNull = "devStNull"
73 devStDown = "devStDown"
74 devStInit = "devStInit"
75 devStConnected = "devStConnected"
76 devStUp = "devStUp"
77)
78
Holger Hildebrandt24d51952020-05-04 14:03:42 +000079//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
80const (
Himani Chawla4d908332020-08-31 12:30:20 +053081 pon = voltha.EventSubCategory_PON
82 //olt = voltha.EventSubCategory_OLT
83 //ont = voltha.EventSubCategory_ONT
84 //onu = voltha.EventSubCategory_ONU
85 //nni = voltha.EventSubCategory_NNI
86 //service = voltha.EventCategory_SERVICE
87 //security = voltha.EventCategory_SECURITY
88 equipment = voltha.EventCategory_EQUIPMENT
89 //processing = voltha.EventCategory_PROCESSING
90 //environment = voltha.EventCategory_ENVIRONMENT
91 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000092)
93
94const (
95 cEventObjectType = "ONU"
96)
97const (
98 cOnuActivatedEvent = "ONU_ACTIVATED"
99)
100
mpagenkof1fc3862021-02-16 10:09:52 +0000101type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000102 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000103 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000104}
105
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000106var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
107 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
108 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
109 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
110 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
111 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
112 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
113 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
114 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000115}
116
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000117const (
118 cNoReconciling = iota
119 cOnuConfigReconciling
120 cSkipOnuConfigReconciling
121)
122
Girish Gowdrae95687a2021-09-08 16:30:58 -0700123// FlowCb is the flow control block containing flow add/delete information along with a response channel
124type FlowCb struct {
125 ctx context.Context // Flow handler context
126 addFlow bool // if true flow to be added, else removed
127 flowItem *of.OfpFlowStats
128 uniPort *cmn.OnuUniPort
129 flowMetaData *voltha.FlowMetadata
130 respChan *chan error // channel to report the Flow handling error
131}
132
Himani Chawla6d2ae152020-09-02 13:11:20 +0530133//deviceHandler will interact with the ONU ? device.
134type deviceHandler struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000135 DeviceID string
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000136 DeviceType string
137 adminState string
138 device *voltha.Device
139 logicalDeviceID string
140 ProxyAddressID string
141 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530142 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000143 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000144
khenaidoo7d3c5582021-08-11 18:09:44 -0400145 coreClient *vgrpc.Client
146 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000147
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800148 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400149 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800150
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000151 pOpenOnuAc *OpenONUAC
152 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530153 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000154 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000155 pOnuOmciDevice *mib.OnuDeviceEntry
156 pOnuTP *avcfg.OnuUniTechProf
157 pOnuMetricsMgr *pmmgr.OnuMetricsManager
158 pAlarmMgr *almgr.OnuAlarmManager
159 pSelfTestHdlr *otst.SelfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000160 exitChannel chan int
161 lockDevice sync.RWMutex
162 pOnuIndication *oop.OnuIndication
163 deviceReason uint8
164 mutexDeviceReason sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000165 pLockStateFsm *uniprt.LockStateFsm
166 pUnlockStateFsm *uniprt.LockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000167
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000168 //flowMgr *OpenOltFlowMgr
169 //eventMgr *OpenOltEventMgr
170 //resourceMgr *rsrcMgr.OpenOltResourceMgr
171
172 //discOnus sync.Map
173 //onus sync.Map
174 //portStats *OpenOltStatisticsMgr
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000175 collectorIsRunning bool
176 mutexCollectorFlag sync.RWMutex
177 stopCollector chan bool
178 alarmManagerIsRunning bool
179 mutextAlarmManagerFlag sync.RWMutex
180 stopAlarmManager chan bool
181 stopHeartbeatCheck chan bool
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000182 uniEntityMap cmn.OnuUniPortMap
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000183 mutexKvStoreContext sync.Mutex
184 lockVlanConfig sync.RWMutex
mpagenkobc4170a2021-08-17 16:42:10 +0000185 lockVlanAdd sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000186 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000187 lockUpgradeFsm sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000188 pOnuUpradeFsm *swupg.OnuUpgradeFsm
mpagenko59862f02021-10-11 08:53:18 +0000189 upgradeCanceled bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000190 reconciling uint8
191 mutexReconcilingFlag sync.RWMutex
192 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000193 mutexReadyForOmciConfig sync.RWMutex
194 readyForOmciConfig bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000195 deletionInProgress bool
196 mutexDeletionInProgressFlag sync.RWMutex
mpagenko38662d02021-08-11 09:45:19 +0000197 pLastUpgradeImageState *voltha.ImageState
198 upgradeFsmChan chan struct{}
Girish Gowdrae95687a2021-09-08 16:30:58 -0700199
200 flowCbChan []chan FlowCb
201 mutexFlowMonitoringRoutineFlag sync.RWMutex
202 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
203 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000204}
205
Himani Chawla6d2ae152020-09-02 13:11:20 +0530206//newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400207func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530208 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400209 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000210 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400211 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000212 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000213 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000214 dh.DeviceType = cloned.Type
215 dh.adminState = "up"
216 dh.device = cloned
217 dh.pOpenOnuAc = adapter
218 dh.exitChannel = make(chan int, 1)
219 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000220 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000221 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000222 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530223 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530224 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000225 dh.stopHeartbeatCheck = make(chan bool, 2)
226 //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 +0000227 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000228 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000229 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000230 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000231 dh.lockUpgradeFsm = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000232 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000233 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000234 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000235 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000236 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000237 dh.pLastUpgradeImageState = &voltha.ImageState{
238 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
239 Reason: voltha.ImageState_UNKNOWN_ERROR,
240 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
241 }
242 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000243
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800244 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
245 dh.pmConfigs = cloned.PmConfigs
246 } /* else {
247 // will be populated when onu_metrics_mananger is initialized.
248 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800249
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000250 // Device related state machine
251 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000252 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000253 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000254 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
255 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
256 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
257 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
258 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000259 },
260 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000261 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
262 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
263 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
264 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
265 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
266 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
267 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
268 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000269 },
270 )
mpagenkoaf801632020-07-03 10:00:42 +0000271
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000272 return &dh
273}
274
Himani Chawla6d2ae152020-09-02 13:11:20 +0530275// start save the device to the data model
276func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000277 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000278 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000279 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000280}
281
Himani Chawla4d908332020-08-31 12:30:20 +0530282/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000283// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530284func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000285 logger.Debug("stopping-device-handler")
286 dh.exitChannel <- 1
287}
Himani Chawla4d908332020-08-31 12:30:20 +0530288*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000289
290// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530291// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000292
Girish Gowdrae0140f02021-02-02 16:55:09 -0800293//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530294func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400295 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000296
dbainbri4d3a0dc2020-12-02 00:33:42 +0000297 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000298 if dh.pDeviceStateFsm.Is(devStNull) {
299 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000300 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000301 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000302 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800303 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
304 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800305 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400306 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000307 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800308 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800309 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000310 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000311 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000312 }
313
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000314}
315
khenaidoo7d3c5582021-08-11 18:09:44 -0400316func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ic.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000317 /* 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 +0530318 //assuming omci message content is hex coded!
319 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000320 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000321 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000322 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000323 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530324 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000325 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000326 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000327 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400328 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 +0530329 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000330 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
331 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530332}
333
khenaidoo7d3c5582021-08-11 18:09:44 -0400334func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ic.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000335 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000336
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000337 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000338 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000339 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
340 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000341 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530342 if dh.pOnuTP == nil {
343 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000344 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000345 log.Fields{"device-id": dh.DeviceID})
346 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530347 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000348 if !dh.IsReadyForOmciConfig() {
349 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
350 "device-state": dh.GetDeviceReasonString()})
351 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530352 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000353 //previous state test here was just this one, now extended for more states to reject the SetRequest:
354 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
355 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530356
Himani Chawla26e555c2020-08-31 12:30:20 +0530357 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000358 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
359 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000360 dh.pOnuTP.LockTpProcMutex()
361 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000362
363 if techProfMsg.UniId > 255 {
364 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000365 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000366 }
367 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000368 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800369 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700370 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800371 return err
372 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700373 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000374
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000375 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530376
Girish Gowdra50e56422021-06-01 16:46:04 -0700377 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400378 case *ic.TechProfileDownloadMessage_TpInstance:
Girish Gowdra50e56422021-06-01 16:46:04 -0700379 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
380 // if there has been some change for some uni TechProfilePath
381 //in order to allow concurrent calls to other dh instances we do not wait for execution here
382 //but doing so we can not indicate problems to the caller (who does what with that then?)
383 //by now we just assume straightforward successful execution
384 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
385 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530386
Girish Gowdra50e56422021-06-01 16:46:04 -0700387 // deadline context to ensure completion of background routines waited for
388 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
389 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
390 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000391
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000392 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700393
394 var wg sync.WaitGroup
395 wg.Add(1) // for the 1 go routine to finish
396 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000397 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700398 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000399 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
400 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 -0700401 return tpErr
402 }
403 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
404 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000405 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700406 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000407 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700408 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000409 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
410 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 -0700411 return kvErr
412 }
413 return nil
414 default:
415 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"tp-path": techProfMsg.TpInstancePath})
416 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700417 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530418 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000419 // no change, nothing really to do - return success
Girish Gowdra50e56422021-06-01 16:46:04 -0700420 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 +0530421 return nil
422}
423
khenaidoo7d3c5582021-08-11 18:09:44 -0400424func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ic.DeleteGemPortMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000425 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530426
427 if dh.pOnuTP == nil {
428 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000429 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000430 log.Fields{"device-id": dh.DeviceID})
431 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530432 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530433 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000434 dh.pOnuTP.LockTpProcMutex()
435 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530436
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000437 if delGemPortMsg.UniId > 255 {
438 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000439 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000440 }
441 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000442 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800443 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700444 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800445 return err
446 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000447 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000448 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000449
Mahir Gunyel9545be22021-07-04 15:53:16 -0700450 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000451 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000452
Himani Chawla26e555c2020-08-31 12:30:20 +0530453}
454
khenaidoo7d3c5582021-08-11 18:09:44 -0400455func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ic.DeleteTcontMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000456 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000457
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000458 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000459 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000460 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
461 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000462 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530463 if dh.pOnuTP == nil {
464 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000465 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000466 log.Fields{"device-id": dh.DeviceID})
467 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530468 }
469
Himani Chawla26e555c2020-08-31 12:30:20 +0530470 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000471 dh.pOnuTP.LockTpProcMutex()
472 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000473
474 if delTcontMsg.UniId > 255 {
475 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000476 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000477 }
478 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700479 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000480 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800481 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000482 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800483 return err
484 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000485 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 +0000486
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000487 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530488
Mahir Gunyel9545be22021-07-04 15:53:16 -0700489 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000490 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000491
Mahir Gunyel9545be22021-07-04 15:53:16 -0700492}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000493
Mahir Gunyel9545be22021-07-04 15:53:16 -0700494func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000495 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
496 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700497 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000498 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
499 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530500 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700501 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000502 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700503 resourceName = "Gem"
504 } else {
505 resourceName = "Tcont"
506 }
507
508 // deadline context to ensure completion of background routines waited for
509 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
510 dctx, cancel := context.WithDeadline(context.Background(), deadline)
511
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000512 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700513
514 var wg sync.WaitGroup
515 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000516 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700517 resource, entryID, &wg)
518 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000519 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
520 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700521 return err
522 }
523
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000524 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
525 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
526 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
527 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700528 var wg2 sync.WaitGroup
529 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
530 wg2.Add(1)
531 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000532 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
533 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700534 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000535 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
536 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700537 return err
538 }
539 }
540 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000541 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700542 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530543 return nil
544}
545
mpagenkodff5dda2020-08-28 11:52:01 +0000546//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000547func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400548 apOfFlowChanges *of.FlowChanges,
549 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700550 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
551 var errorsList []error
552 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000553 //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 +0000554 if apOfFlowChanges.ToRemove != nil {
555 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000556 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000557 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000558 "device-id": dh.DeviceID})
559 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700560 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000561 continue
562 }
563 flowInPort := flow.GetInPort(flowItem)
564 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000565 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
566 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700567 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000568 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000569 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000570 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000571 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000572 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000573 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000574 continue
575 } else {
576 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000577 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000578 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
579 loUniPort = uniPort
580 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000581 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000582 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000583 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000584 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700585 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000586 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000587 }
588 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000589 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000590 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
591 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700592
593 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
594 // Step1 : Fill flowControlBlock
595 // Step2 : Push the flowControlBlock to ONU channel
596 // Step3 : Wait on response channel for response
597 // Step4 : Return error value
598 startTime := time.Now()
599 respChan := make(chan error)
600 flowCb := FlowCb{
601 ctx: ctx,
602 addFlow: false,
603 flowItem: flowItem,
604 flowMetaData: nil,
605 uniPort: loUniPort,
606 respChan: &respChan,
607 }
608 dh.flowCbChan[loUniPort.UniID] <- flowCb
609 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
610 // Wait on the channel for flow handlers return value
611 retError = <-respChan
612 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
613 if retError != nil {
614 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
615 log.Fields{"device-id": dh.DeviceID, "error": retError})
616 errorsList = append(errorsList, retError)
617 continue
618 }
619 } else {
620 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
621 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000622 }
623 }
624 }
625 }
mpagenko01e726e2020-10-23 09:45:29 +0000626 if apOfFlowChanges.ToAdd != nil {
627 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
628 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000629 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000630 "device-id": dh.DeviceID})
631 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700632 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000633 continue
634 }
635 flowInPort := flow.GetInPort(flowItem)
636 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000637 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
638 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700639 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000640 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000641 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000642 } else if flowInPort == dh.ponPortNumber {
643 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000644 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000645 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000646 continue
647 } else {
648 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000649 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000650 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
651 loUniPort = uniPort
652 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000653 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000654 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000655 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000656 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700657 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000658 continue
mpagenko01e726e2020-10-23 09:45:29 +0000659 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000660 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
661 // if not, we just throw some error here to have an indication about that, if we really need to support that
662 // then we would need to create some means to activate the internal stored flows
663 // after the device gets active automatically (and still with its dependency to the TechProfile)
664 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
665 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000666 if !dh.IsReadyForOmciConfig() {
667 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
668 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700669 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
670 errorsList = append(errorsList, retError)
671 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000672 }
673
mpagenko01e726e2020-10-23 09:45:29 +0000674 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000675 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000676 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
677 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700678 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
679 // Step1 : Fill flowControlBlock
680 // Step2 : Push the flowControlBlock to ONU channel
681 // Step3 : Wait on response channel for response
682 // Step4 : Return error value
683 startTime := time.Now()
684 respChan := make(chan error)
685 flowCb := FlowCb{
686 ctx: ctx,
687 addFlow: true,
688 flowItem: flowItem,
689 flowMetaData: apFlowMetaData,
690 uniPort: loUniPort,
691 respChan: &respChan,
692 }
693 dh.flowCbChan[loUniPort.UniID] <- flowCb
694 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
695 // Wait on the channel for flow handlers return value
696 retError = <-respChan
697 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
698 if retError != nil {
699 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
700 log.Fields{"device-id": dh.DeviceID, "error": retError})
701 errorsList = append(errorsList, retError)
702 continue
703 }
704 } else {
705 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
706 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000707 }
708 }
709 }
710 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700711 if len(errorsList) > 0 {
712 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
713 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
714 }
715 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000716}
717
Himani Chawla6d2ae152020-09-02 13:11:20 +0530718//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000719//following are the expected device states after this activity:
720//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
721// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000722func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
723 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000724
mpagenko900ee4b2020-10-12 11:56:34 +0000725 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000726 //note that disableDevice sequences in some 'ONU active' state may yield also
727 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000728 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000729 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000730 //disable-device shall be just a UNi/ONU-G related admin state setting
731 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000732
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000733 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000734 // disable UNI ports/ONU
735 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
736 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000737 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000738 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000739 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000740 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000741 }
742 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000743 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000744 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -0400745 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000746 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -0400747 ConnStatus: voltha.ConnectStatus_REACHABLE,
748 OperStatus: voltha.OperStatus_UNKNOWN,
749 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000750 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000751 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000752 }
mpagenko01e726e2020-10-23 09:45:29 +0000753 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000754
755 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000756 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000757 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300758 }
759}
760
Himani Chawla6d2ae152020-09-02 13:11:20 +0530761//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000762func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
763 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000764
mpagenkoaa3afe92021-05-21 16:20:58 +0000765 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000766 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
767 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
768 // for real ONU's that should have nearly no influence
769 // Note that for real ONU's there is anyway a problematic situation with following sequence:
770 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
771 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
772 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000773 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000774
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000775 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000776 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000777 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000778 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000779 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000780 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000781 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000782 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300783}
784
dbainbri4d3a0dc2020-12-02 00:33:42 +0000785func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000786 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000787
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000788 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000789 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000790 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000791 return
792 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000793 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000794 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000795 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000796 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000797 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000798 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000799 dh.StopReconciling(ctx, false)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000800 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000801 }
Himani Chawla4d908332020-08-31 12:30:20 +0530802 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000803 pDevEntry.MutexPersOnuConfig.RLock()
804 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
805 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
806 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
807 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
808 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000809 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000810}
811
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000812func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) {
813 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000814
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000815 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000816 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000817 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
818 if !dh.IsSkipOnuConfigReconciling() {
819 dh.StopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000820 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000821 return
822 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000823 dh.pOnuTP.LockTpProcMutex()
824 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000825
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000826 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000827 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000828 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
829 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000830 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000831 log.Fields{"device-id": dh.DeviceID})
832 if !dh.IsSkipOnuConfigReconciling() {
833 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000834 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000835 return
836 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000837 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700838 techProfsFound := false
839 techProfInstLoadFailed := false
840outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000841 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000842 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
843 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000844 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000845 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000846 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000847 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000848 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
849 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000850 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000851 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000852 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700853 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800854 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700855 // Request the TpInstance again from the openolt adapter in case of reconcile
khenaidoo7d3c5582021-08-11 18:09:44 -0400856 iaTechTpInst, err := dh.getTechProfileInstanceFromParentAdapter(ctx,
857 dh.device.ProxyAddress.AdapterEndpoint,
858 &ic.TechProfileInstanceRequestMessage{
859 DeviceId: dh.device.Id,
860 TpInstancePath: uniData.PersTpPathMap[tpID],
861 ParentDeviceId: dh.parentID,
862 ParentPonPort: dh.device.ParentPortNo,
863 OnuId: dh.device.ProxyAddress.OnuId,
864 UniId: uint32(uniData.PersUniID),
865 })
Girish Gowdra50e56422021-06-01 16:46:04 -0700866 if err != nil || iaTechTpInst == nil {
867 logger.Errorw(ctx, "error fetching tp instance",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000868 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 -0700869 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
870 break outerLoop
871 }
872 var tpInst tech_profile.TechProfileInstance
873 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400874 case *ic.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700875 tpInst = *techTpInst.TpInstance
mpagenko2dc896e2021-08-02 12:03:59 +0000876 logger.Debugw(ctx, "received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000877 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700878 default: // do not support epon or other tech
mpagenko2dc896e2021-08-02 12:03:59 +0000879 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000880 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700881 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
882 break outerLoop
883 }
884
Girish Gowdra041dcb32020-11-16 16:54:30 -0800885 // deadline context to ensure completion of background routines waited for
886 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
887 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000888 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000889
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000890 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800891 var wg sync.WaitGroup
892 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000893 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000894 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000895 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
896 logger.Errorw(ctx, err.Error(), log.Fields{"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
Girish Gowdra041dcb32020-11-16 16:54:30 -0800899 }
mpagenko2dc896e2021-08-02 12:03:59 +0000900 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000901 if len(uniData.PersFlowParams) != 0 {
902 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000903 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000904 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000905 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000906 } // for all UNI entries from SOnuPersistentData
907 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
908 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000909 }
mpagenko2dc896e2021-08-02 12:03:59 +0000910
911 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
912 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
913}
914
915func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
916 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
917 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000918 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000919 log.Fields{"device-id": dh.DeviceID})
920 if !dh.IsSkipOnuConfigReconciling() {
921 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000922 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000923 return
924 }
mpagenko2dc896e2021-08-02 12:03:59 +0000925 if abTechProfInstLoadFailed {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000926 dh.SetDeviceReason(cmn.DrTechProfileConfigDownloadFailed)
927 dh.StopReconciling(ctx, false)
Girish Gowdra50e56422021-06-01 16:46:04 -0700928 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000929 } else if dh.IsSkipOnuConfigReconciling() {
930 dh.SetDeviceReason(cmn.DrTechProfileConfigDownloadSuccess)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000931 }
mpagenko2dc896e2021-08-02 12:03:59 +0000932 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000933 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000934 log.Fields{"device-id": dh.DeviceID})
935 if !dh.IsSkipOnuConfigReconciling() {
936 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000937 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000938 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000939}
940
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000941func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
942 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000943
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000944 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000945 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000946 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
947 if !dh.IsSkipOnuConfigReconciling() {
948 dh.StopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000949 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000950 return
951 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000952
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000953 pDevEntry.MutexPersOnuConfig.RLock()
954 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
955 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000956 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000957 log.Fields{"device-id": dh.DeviceID})
958 if !dh.IsSkipOnuConfigReconciling() {
959 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000960 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000961 return
962 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000963 flowsFound := false
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000964 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000965 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
966 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000967 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000968 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000969 continue
970 }
971 if len(uniData.PersTpPathMap) == 0 {
972 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000973 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000974 // It doesn't make sense to configure any flows if no TPs are available
975 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000976 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000977 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
978 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000979 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000980 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000981
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000982 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000983 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -0700984 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000985 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000986 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
987 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
988 if !dh.IsSkipOnuConfigReconciling() {
989 dh.StopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000990 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000991 return
992 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000993 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200994 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000995 flowsProcessed := 0
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000996 pDevEntry.SetReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000997 for _, flowData := range uniData.PersFlowParams {
mpagenko2dc896e2021-08-02 12:03:59 +0000998 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000999 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001000 if flowsProcessed == len(uniData.PersFlowParams)-1 {
1001 lastFlowToReconcile = true
1002 }
mpagenko01e726e2020-10-23 09:45:29 +00001003 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenko7d14de12021-07-27 08:31:56 +00001004 dh.lockVlanConfig.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001005 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001006 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +00001007 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Girish Gowdrae95687a2021-09-08 16:30:58 -07001008 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter, nil); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001009 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001010 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001011 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001012 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00001013 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Girish Gowdrae95687a2021-09-08 16:30:58 -07001014 uint8(flowData.VlanRuleParams.SetPcp), cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001015 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001016 }
1017 }
mpagenko7d14de12021-07-27 08:31:56 +00001018 dh.lockVlanConfig.Unlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001019 flowsProcessed++
mpagenko2dc896e2021-08-02 12:03:59 +00001020 } //for all flows of this UNI
1021 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001022 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID, "flowsProcessed": flowsProcessed,
1023 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1024 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001025 // this can't be used as global finished reconciling flag because
1026 // assumes is getting called before the state machines for the last flow is completed,
1027 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001028 //dh.SetReconcilingFlows(false)
1029 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1030 } // for all UNI entries from SOnuPersistentData
1031 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001032
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001033 if !flowsFound {
1034 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001035 log.Fields{"device-id": dh.DeviceID})
1036 if !dh.IsSkipOnuConfigReconciling() {
1037 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001038 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001039 return
1040 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001041 if dh.IsSkipOnuConfigReconciling() {
1042 dh.SetDeviceReason(cmn.DrOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001043 }
1044}
1045
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001046func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001047 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.DeviceID})
1048 dh.StopReconciling(ctx, true)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001049}
1050
dbainbri4d3a0dc2020-12-02 00:33:42 +00001051func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001052 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001053
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001054 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001055 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001056 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001057 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001058 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001059 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001060
1061 // deadline context to ensure completion of background routines waited for
1062 //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 +05301063 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001064 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001065
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001066 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001067
1068 var wg sync.WaitGroup
1069 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001070 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001071 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001072
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001073 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001074 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001075}
1076
mpagenko15ff4a52021-03-02 10:09:20 +00001077//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1078// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001079// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001080//was and is called in background - error return does not make sense
1081func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001082 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001083 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001084 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001085 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001086 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001087 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301088 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001089 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001090 return
Himani Chawla4d908332020-08-31 12:30:20 +05301091 }
mpagenko01e726e2020-10-23 09:45:29 +00001092
1093 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001094 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001095
dbainbri4d3a0dc2020-12-02 00:33:42 +00001096 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001097 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001098 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001099 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001100 ConnStatus: voltha.ConnectStatus_REACHABLE,
1101 OperStatus: voltha.OperStatus_DISCOVERED,
1102 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001103 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001104 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001105 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001106 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001107 if err := dh.deviceReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001108 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001109 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001110 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001111 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1112 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1113 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1114 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001115}
1116
mpagenkoc8bba412021-01-15 15:38:44 +00001117//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001118// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001119func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001120 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001121 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001122 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001123
1124 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001125 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001126 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001127 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1128 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001129 }
1130
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001131 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001132 var inactiveImageID uint16
1133 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1134 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001135 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1136 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001137 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001138 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001139 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001140 if err == nil {
1141 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1142 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001143 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001144 }
1145 } else {
1146 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001147 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001148 }
mpagenko15ff4a52021-03-02 10:09:20 +00001149 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001150 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001151 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001152 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1153 dh.upgradeCanceled = true
1154 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1155 }
mpagenko38662d02021-08-11 09:45:19 +00001156 //no effort spent anymore for the old API to automatically cancel and restart the download
1157 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001158 }
mpagenko15ff4a52021-03-02 10:09:20 +00001159 } else {
1160 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001161 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001162 }
1163 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001164 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1165 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001166 }
1167 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001168}
1169
mpagenkoc26d4c02021-05-06 14:27:57 +00001170//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1171// after the OnuImage has been downloaded to the adapter, called in background
1172func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001173 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001174
1175 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001176 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001177 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001178 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001179 return
1180 }
1181
1182 var inactiveImageID uint16
1183 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1184 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001185 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001186
mpagenko59862f02021-10-11 08:53:18 +00001187 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001188 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001189 // but must be still locked at calling createOnuUpgradeFsm
1190 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1191 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1192 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001193 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1194 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001195 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001196 //flush the remove upgradeFsmChan channel
1197 select {
1198 case <-dh.upgradeFsmChan:
1199 logger.Debug(ctx, "flushed-upgrade-fsm-channel")
1200 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001201 }
mpagenko59862f02021-10-11 08:53:18 +00001202 dh.lockUpgradeFsm.Unlock()
1203 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1204 dh.upgradeCanceled = true
1205 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1206 }
mpagenko38662d02021-08-11 09:45:19 +00001207 select {
1208 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001209 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001210 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1211 return
1212 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001213 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001214 }
mpagenko59862f02021-10-11 08:53:18 +00001215 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001216 }
mpagenko38662d02021-08-11 09:45:19 +00001217
1218 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001219 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001220 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001221 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001222 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001223 if err == nil {
1224 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1225 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1226 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001227 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001228 return
1229 }
mpagenko38662d02021-08-11 09:45:19 +00001230 } else {
1231 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001232 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001233 }
1234 return
1235 }
1236 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001237 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001238}
1239
1240//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001241func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1242 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001243 var err error
1244 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1245 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1246 // 2.) activation of the inactive image
1247
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001248 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001249 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001250 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1251 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001252 }
1253 dh.lockUpgradeFsm.RLock()
1254 if dh.pOnuUpradeFsm != nil {
1255 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001256 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001257 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001258 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1259 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001260 }
mpagenko59862f02021-10-11 08:53:18 +00001261 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1262 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1263 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1264 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001265 // use the OnuVendor identification from this device for the internal unique name
1266 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001267 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001268 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001269 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001270 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001271 "device-id": dh.DeviceID, "error": err})
1272 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001273 }
mpagenko183647c2021-06-08 15:25:04 +00001274 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001275 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001276 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001277 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001278 } //else
1279 dh.lockUpgradeFsm.RUnlock()
1280
1281 // 2.) check if requested image-version equals the inactive one and start its activation
1282 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1283 var inactiveImageID uint16
1284 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1285 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001286 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1287 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001288 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001289 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001290 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001291 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001292 if err == nil {
1293 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1294 inactiveImageID, aCommitRequest); err != nil {
1295 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001296 "device-id": dh.DeviceID, "error": err})
1297 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001298 }
1299 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001300 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001301 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001302 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001303 } //else
1304 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001305 "device-id": dh.DeviceID, "error": err})
1306 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001307}
1308
1309//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001310func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1311 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001312 var err error
1313 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1314 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1315 // 2.) commitment of the active image
1316
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001317 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001318 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001319 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1320 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001321 }
1322 dh.lockUpgradeFsm.RLock()
1323 if dh.pOnuUpradeFsm != nil {
1324 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001325 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001326 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001327 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1328 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001329 }
mpagenko59862f02021-10-11 08:53:18 +00001330 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1331 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1332 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1333 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001334 // use the OnuVendor identification from this device for the internal unique name
1335 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001336 // 1.) check a started upgrade process and relay the commitment request to it
1337 // the running upgrade may be based either on the imageIdentifier (started from download)
1338 // or on the imageVersion (started from pure activation)
1339 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1340 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001341 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001342 "device-id": dh.DeviceID, "error": err})
1343 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001344 }
mpagenko183647c2021-06-08 15:25:04 +00001345 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001346 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001347 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001348 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001349 } //else
1350 dh.lockUpgradeFsm.RUnlock()
1351
mpagenko183647c2021-06-08 15:25:04 +00001352 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001353 var activeImageID uint16
1354 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1355 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001356 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1357 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001358 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001359 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001360 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001361 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001362 if err == nil {
1363 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1364 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001365 "device-id": dh.DeviceID, "error": err})
1366 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001367 }
1368 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001369 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001370 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001371 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001372 } //else
1373 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001374 "device-id": dh.DeviceID, "error": err})
1375 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001376}
1377
mpagenkoaa3afe92021-05-21 16:20:58 +00001378func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001379 aVersion string) *voltha.ImageState {
1380 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001381 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001382 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001383 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001384 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1385 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1386 if aVersion == dh.pLastUpgradeImageState.Version {
1387 pImageState = dh.pLastUpgradeImageState
1388 } else { //state request for an image version different from last processed image version
1389 pImageState = &voltha.ImageState{
1390 Version: aVersion,
1391 //we cannot state something concerning this version
1392 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1393 Reason: voltha.ImageState_NO_ERROR,
1394 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1395 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001396 }
1397 }
mpagenko38662d02021-08-11 09:45:19 +00001398 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001399}
1400
1401func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1402 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001403 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001404 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001405 dh.lockUpgradeFsm.RLock()
1406 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001407 dh.lockUpgradeFsm.RUnlock()
1408 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001409 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001410 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1411 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1412 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1413 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1414 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1415 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001416 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1417 dh.upgradeCanceled = true
1418 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1419 }
mpagenko45586762021-10-01 08:30:22 +00001420 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001421 } else {
mpagenko45586762021-10-01 08:30:22 +00001422 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001423 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1424 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1425 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1426 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1427 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1428 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001429 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1430 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001431 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1432 //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 +00001433 }
1434}
1435
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001436func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1437
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001438 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001439
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001440 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001441 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001442 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1443 pDevEntry.MutexOnuImageStatus.Lock()
1444 pDevEntry.POnuImageStatus = onuImageStatus
1445 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001446
1447 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001448 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001449 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1450 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001451 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1452 pDevEntry.MutexOnuImageStatus.Lock()
1453 pDevEntry.POnuImageStatus = nil
1454 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001455 return images, err
1456}
1457
Himani Chawla6d2ae152020-09-02 13:11:20 +05301458// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001459// #####################################################################################
1460
1461// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301462// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001463
dbainbri4d3a0dc2020-12-02 00:33:42 +00001464func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001465 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 +00001466}
1467
1468// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001469func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001470
dbainbri4d3a0dc2020-12-02 00:33:42 +00001471 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001472 var err error
1473
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001474 // populate what we know. rest comes later after mib sync
1475 dh.device.Root = false
1476 dh.device.Vendor = "OpenONU"
1477 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001478 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
1479 dh.SetDeviceReason(cmn.DrActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001480
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001481 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001482
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001483 if !dh.IsReconciling() {
1484 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001485 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1486 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1487 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301488 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001489 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001490 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001491 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001492 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001493
Himani Chawla4d908332020-08-31 12:30:20 +05301494 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001495 dh.ponPortNumber = dh.device.ParentPortNo
1496
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001497 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1498 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1499 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001500 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001501 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301502 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001503
1504 /*
1505 self._pon = PonPort.create(self, self._pon_port_number)
1506 self._pon.add_peer(self.parent_id, self._pon_port_number)
1507 self.logger.debug('adding-pon-port-to-agent',
1508 type=self._pon.get_port().type,
1509 admin_state=self._pon.get_port().admin_state,
1510 oper_status=self._pon.get_port().oper_status,
1511 )
1512 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001513 if !dh.IsReconciling() {
1514 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001515 var ponPortNo uint32 = 1
1516 if dh.ponPortNumber != 0 {
1517 ponPortNo = dh.ponPortNumber
1518 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001519
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001520 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001521 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001522 PortNo: ponPortNo,
1523 Label: fmt.Sprintf("pon-%d", ponPortNo),
1524 Type: voltha.Port_PON_ONU,
1525 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301526 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001527 PortNo: ponPortNo}}, // Peer port is parent's port number
1528 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001529 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001530 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001531 e.Cancel(err)
1532 return
1533 }
1534 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001535 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001536 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001537 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001538}
1539
1540// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001541func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001542
dbainbri4d3a0dc2020-12-02 00:33:42 +00001543 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001544 var err error
1545 /*
1546 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1547 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1548 return nil
1549 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001550 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1551 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001552 e.Cancel(err)
1553 return
1554 }
1555
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001556 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001557 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001558 // reconcilement will be continued after mib download is done
1559 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001560
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001561 /*
1562 ############################################################################
1563 # Setup Alarm handler
1564 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1565 device.serial_number)
1566 ############################################################################
1567 # Setup PM configuration for this device
1568 # Pass in ONU specific options
1569 kwargs = {
1570 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1571 'heartbeat': self.heartbeat,
1572 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1573 }
1574 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1575 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1576 self.logical_device_id, device.serial_number,
1577 grouped=True, freq_override=False, **kwargs)
1578 pm_config = self._pm_metrics.make_proto()
1579 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1580 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1581 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1582
1583 # Note, ONU ID and UNI intf set in add_uni_port method
1584 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1585 ani_ports=[self._pon])
1586
1587 # Code to Run OMCI Test Action
1588 kwargs_omci_test_action = {
1589 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1590 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1591 }
1592 serial_number = device.serial_number
1593 self._test_request = OmciTestRequest(self.core_proxy,
1594 self.omci_agent, self.device_id,
1595 AniG, serial_number,
1596 self.logical_device_id,
1597 exclusive=False,
1598 **kwargs_omci_test_action)
1599
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001600 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001601 else:
1602 self.logger.info('onu-already-activated')
1603 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001604
dbainbri4d3a0dc2020-12-02 00:33:42 +00001605 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001606}
1607
1608// doStateConnected get the device info and update to voltha core
1609// for comparison of the original method (not that easy to uncomment): compare here:
1610// voltha-openolt-adapter/adaptercore/device_handler.go
1611// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001612func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001613
dbainbri4d3a0dc2020-12-02 00:33:42 +00001614 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301615 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001616 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001617 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001618}
1619
1620// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001621func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001622
dbainbri4d3a0dc2020-12-02 00:33:42 +00001623 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301624 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001625 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001626 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001627
1628 /*
1629 // Synchronous call to update device state - this method is run in its own go routine
1630 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1631 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001632 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 +00001633 return err
1634 }
1635 return nil
1636 */
1637}
1638
1639// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001640func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001641
dbainbri4d3a0dc2020-12-02 00:33:42 +00001642 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001643 var err error
1644
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001645 device := dh.device
1646 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001647 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001648 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001649 e.Cancel(err)
1650 return
1651 }
1652
1653 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001655 /*
1656 // Update the all ports state on that device to disable
1657 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001658 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001659 return er
1660 }
1661
1662 //Update the device oper state and connection status
1663 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1664 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1665 dh.device = cloned
1666
1667 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001668 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001669 return er
1670 }
1671
1672 //get the child device for the parent device
1673 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1674 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001675 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001676 return err
1677 }
1678 for _, onuDevice := range onuDevices.Items {
1679
1680 // Update onu state as down in onu adapter
1681 onuInd := oop.OnuIndication{}
1682 onuInd.OperState = "down"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001683 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001684 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1685 if er != nil {
1686 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001687 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001688 //Do not return here and continue to process other ONUs
1689 }
1690 }
1691 // * Discovered ONUs entries need to be cleared , since after OLT
1692 // is up, it starts sending discovery indications again* /
1693 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001694 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001695 return nil
1696 */
Himani Chawla4d908332020-08-31 12:30:20 +05301697 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001698 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001699 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001700}
1701
Himani Chawla6d2ae152020-09-02 13:11:20 +05301702// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001703// #################################################################################
1704
1705// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301706// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001707
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001708//GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
1709func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001710 dh.lockDevice.RLock()
1711 pOnuDeviceEntry := dh.pOnuOmciDevice
1712 if aWait && pOnuDeviceEntry == nil {
1713 //keep the read sema short to allow for subsequent write
1714 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001715 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001716 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1717 // so it might be needed to wait here for that event with some timeout
1718 select {
1719 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001720 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001721 return nil
1722 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001723 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001724 // if written now, we can return the written value without sema
1725 return dh.pOnuOmciDevice
1726 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001727 }
mpagenko3af1f032020-06-10 08:53:41 +00001728 dh.lockDevice.RUnlock()
1729 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001730}
1731
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001732//setDeviceHandlerEntries sets the ONU device entry within the handler
1733func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1734 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001735 dh.lockDevice.Lock()
1736 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001737 dh.pOnuOmciDevice = apDeviceEntry
1738 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001739 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301740 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001741 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001742}
1743
Himani Chawla6d2ae152020-09-02 13:11:20 +05301744//addOnuDeviceEntry creates a new ONU device or returns the existing
1745func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001746 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001747
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001748 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001749 if deviceEntry == nil {
1750 /* costum_me_map in python code seems always to be None,
1751 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1752 /* also no 'clock' argument - usage open ...*/
1753 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001754 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1755 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1756 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1757 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1758 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001759 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001760 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001761 // fire deviceEntry ready event to spread to possibly waiting processing
1762 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001763 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001764 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001765 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001766 }
1767 // might be updated with some error handling !!!
1768 return nil
1769}
1770
dbainbri4d3a0dc2020-12-02 00:33:42 +00001771func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1772 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001773 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1774
1775 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001776
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001777 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001778 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001779 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1780 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001781 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001782 if !dh.IsReconciling() {
1783 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001784 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001785 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001786 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001787 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001788 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001789
1790 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001791 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001792 OperStatus: voltha.OperStatus_ACTIVATING,
1793 ConnStatus: voltha.ConnectStatus_REACHABLE,
1794 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001795 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001796 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001797 }
1798 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001799 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001800 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001801
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001802 pDevEntry.MutexPersOnuConfig.RLock()
1803 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1804 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001805 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 +00001806 log.Fields{"device-id": dh.DeviceID})
1807 dh.StopReconciling(ctx, true)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001808 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001809 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001810 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001811 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001812 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1813 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1814 // 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 +00001815 // 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 +00001816 // so let's just try to keep it simple ...
1817 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001818 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001819 if err != nil || device == nil {
1820 //TODO: needs to handle error scenarios
1821 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1822 return errors.New("Voltha Device not found")
1823 }
1824 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001825
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001826 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001827 return err
mpagenko3af1f032020-06-10 08:53:41 +00001828 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001829
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001830 _ = dh.deviceReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001831
1832 /* this might be a good time for Omci Verify message? */
1833 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001834 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001835 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001836 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001837 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001838
1839 /* give the handler some time here to wait for the OMCi verification result
1840 after Timeout start and try MibUpload FSM anyway
1841 (to prevent stopping on just not supported OMCI verification from ONU) */
1842 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001843 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001844 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001845 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001846 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001847 }
1848
1849 /* In py code it looks earlier (on activate ..)
1850 # Code to Run OMCI Test Action
1851 kwargs_omci_test_action = {
1852 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1853 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1854 }
1855 serial_number = device.serial_number
1856 self._test_request = OmciTestRequest(self.core_proxy,
1857 self.omci_agent, self.device_id,
1858 AniG, serial_number,
1859 self.logical_device_id,
1860 exclusive=False,
1861 **kwargs_omci_test_action)
1862 ...
1863 # Start test requests after a brief pause
1864 if not self._test_request_started:
1865 self._test_request_started = True
1866 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1867 reactor.callLater(tststart, self._test_request.start_collector)
1868
1869 */
1870 /* which is then: in omci_test_request.py : */
1871 /*
1872 def start_collector(self, callback=None):
1873 """
1874 Start the collection loop for an adapter if the frequency > 0
1875
1876 :param callback: (callable) Function to call to collect PM data
1877 """
1878 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1879 if callback is None:
1880 callback = self.perform_test_omci
1881
1882 if self.lc is None:
1883 self.lc = LoopingCall(callback)
1884
1885 if self.default_freq > 0:
1886 self.lc.start(interval=self.default_freq / 10)
1887
1888 def perform_test_omci(self):
1889 """
1890 Perform the initial test request
1891 """
1892 ani_g_entities = self._device.configuration.ani_g_entities
1893 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1894 is not None else None
1895 self._entity_id = ani_g_entities_ids[0]
1896 self.logger.info('perform-test', entity_class=self._entity_class,
1897 entity_id=self._entity_id)
1898 try:
1899 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1900 result = yield self._device.omci_cc.send(frame)
1901 if not result.fields['omci_message'].fields['success_code']:
1902 self.logger.info('Self-Test Submitted Successfully',
1903 code=result.fields[
1904 'omci_message'].fields['success_code'])
1905 else:
1906 raise TestFailure('Test Failure: {}'.format(
1907 result.fields['omci_message'].fields['success_code']))
1908 except TimeoutError as e:
1909 self.deferred.errback(failure.Failure(e))
1910
1911 except Exception as e:
1912 self.logger.exception('perform-test-Error', e=e,
1913 class_id=self._entity_class,
1914 entity_id=self._entity_id)
1915 self.deferred.errback(failure.Failure(e))
1916
1917 */
1918
1919 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001920 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001921
mpagenko1cc3cb42020-07-27 15:24:38 +00001922 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1923 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1924 * 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 +05301925 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001926 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001927 //call MibUploadFSM - transition up to state UlStInSync
1928 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001929 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001930 if pMibUlFsm.Is(mib.UlStDisabled) {
1931 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
1932 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
1933 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301934 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001935 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301936 //Determine ONU status and start/re-start MIB Synchronization tasks
1937 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001938 if pDevEntry.IsNewOnu() {
1939 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
1940 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
1941 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001942 }
Himani Chawla4d908332020-08-31 12:30:20 +05301943 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001944 if err := pMibUlFsm.Event(mib.UlEvExamineMds); err != nil {
1945 logger.Errorw(ctx, "MibSyncFsm: Can't go to state examine_mds", log.Fields{"device-id": dh.DeviceID, "err": err})
1946 return fmt.Errorf("can't go to examine_mds: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301947 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001948 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001949 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001950 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001951 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001952 "device-id": dh.DeviceID})
1953 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001954 }
1955 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001956 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
1957 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001958 }
1959 return nil
1960}
1961
dbainbri4d3a0dc2020-12-02 00:33:42 +00001962func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001963 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001964 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001965 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
1966 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001967
mpagenko900ee4b2020-10-12 11:56:34 +00001968 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1969 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1970 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001971 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001972 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001973 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001974 // abort: system behavior is just unstable ...
1975 return err
1976 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001977 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001978 _ = 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 +00001979
1980 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1981 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1982 //stop the device entry which resets the attached omciCC
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001983 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001984 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001985 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
1986 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001987 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001988 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001989
1990 //TODO!!! remove existing traffic profiles
1991 /* from py code, if TP's exist, remove them - not yet implemented
1992 self._tp = dict()
1993 # Let TP download happen again
1994 for uni_id in self._tp_service_specific_task:
1995 self._tp_service_specific_task[uni_id].clear()
1996 for uni_id in self._tech_profile_download_done:
1997 self._tech_profile_download_done[uni_id].clear()
1998 */
1999
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002000 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002001
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002002 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002003
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002004 if err := dh.deviceReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002005 // abort: system behavior is just unstable ...
2006 return err
2007 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002008 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002009 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002010 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002011 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002012 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2013 OperStatus: voltha.OperStatus_DISCOVERED,
2014 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002015 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002016 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002017 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002018 // abort: system behavior is just unstable ...
2019 return err
2020 }
2021 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002022 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002023 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002024 return nil
2025}
2026
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002027func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002028 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2029 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2030 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2031 // and using the stop/reset event should never harm
2032
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002033 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002034 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002035 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2036 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00002037 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002038 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002039 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002040 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002041 pDevEntry.MutexOnuImageStatus.RLock()
2042 if pDevEntry.POnuImageStatus != nil {
2043 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002044 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002045 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002046
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002047 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002048 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002049 }
2050 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002051 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002052 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002053 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002054 }
2055 //port lock/unlock FSM's may be active
2056 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002057 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002058 }
2059 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002060 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002061 }
2062 //techProfile related PonAniConfigFsm FSM may be active
2063 if dh.pOnuTP != nil {
2064 // should always be the case here
2065 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002066 if dh.pOnuTP.PAniConfigFsm != nil {
2067 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2068 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002069 }
mpagenko900ee4b2020-10-12 11:56:34 +00002070 }
2071 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002072 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002073 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002074 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002075 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002076 dh.lockVlanConfig.RUnlock()
2077 //reset of all Fsm is always accompanied by global persistency data removal
2078 // no need to remove specific data
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00002079 pVlanFilterFsm.RequestClearPersistency(ctx, false)
mpagenko7d6bb022021-03-11 15:07:55 +00002080 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002081 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002082 } else {
2083 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002084 }
2085 }
2086 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002087 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002088 // Stop collector routine
2089 dh.stopCollector <- true
2090 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002091 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302092 dh.stopAlarmManager <- true
2093 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002094 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002095 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002096 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302097
Girish Gowdrae95687a2021-09-08 16:30:58 -07002098 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2099
mpagenko80622a52021-02-09 16:53:23 +00002100 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002101 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002102 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002103 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002104 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002105 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002106 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002107 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2108 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2109 // (even though it may also run into direct cancellation, a bit hard to verify here)
2110 // so don't set 'dh.upgradeCanceled = true' here!
2111 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2112 }
mpagenko38662d02021-08-11 09:45:19 +00002113 }
mpagenko80622a52021-02-09 16:53:23 +00002114
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002115 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002116 return nil
2117}
2118
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002119func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2120 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 +05302121
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002122 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002123 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002124 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002125 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002126 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002127 _ = dh.deviceReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling())
2128 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002129
mpagenkoa40e99a2020-11-17 13:50:39 +00002130 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2131 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2132 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2133 * disable/enable toggling here to allow traffic
2134 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2135 * like the py comment says:
2136 * # start by locking all the unis till mib sync and initial mib is downloaded
2137 * # this way we can capture the port down/up events when we are ready
2138 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302139
mpagenkoa40e99a2020-11-17 13:50:39 +00002140 // Init Uni Ports to Admin locked state
2141 // *** should generate UniLockStateDone event *****
2142 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002143 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002144 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002145 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002146 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002147 }
2148}
2149
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002150func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2151 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302152 /* Mib download procedure -
2153 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2154 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002155 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002156 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002157 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002158 return
2159 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002160 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302161 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002162 if pMibDlFsm.Is(mib.DlStDisabled) {
2163 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2164 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 +05302165 // maybe try a FSM reset and then again ... - TODO!!!
2166 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002167 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302168 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002169 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2170 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302171 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002172 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302173 //Begin MIB data download (running autonomously)
2174 }
2175 }
2176 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002177 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002178 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302179 // maybe try a FSM reset and then again ... - TODO!!!
2180 }
2181 /***** Mib download started */
2182 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002183 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302184 }
2185}
2186
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002187func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2188 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302189 //initiate DevStateUpdate
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002190 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002191 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002192 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002193 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2194 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2195 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2196 dh.checkOnOnuImageCommit(ctx)
khenaidoo7d3c5582021-08-11 18:09:44 -04002197 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002198 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002199 ConnStatus: voltha.ConnectStatus_REACHABLE,
2200 OperStatus: voltha.OperStatus_ACTIVE,
2201 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302202 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002203 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302204 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002205 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302206 }
2207 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002208 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002209 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302210 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002211 _ = dh.deviceReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002212
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002213 if !dh.GetCollectorIsRunning() {
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002214 // Start PM collector routine
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002215 go dh.StartCollector(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002216 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002217 if !dh.GetAlarmManagerIsRunning(ctx) {
2218 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002219 }
2220
Girish Gowdrae95687a2021-09-08 16:30:58 -07002221 // Start flow handler routines per UNI
2222 for _, uniPort := range dh.uniEntityMap {
2223 // only if this port was enabled for use by the operator at startup
2224 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2225 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2226 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2227 }
2228 }
2229 }
2230
Girish Gowdrae0140f02021-02-02 16:55:09 -08002231 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002232 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002233 // There is no way we should be landing here, but if we do then
2234 // there is nothing much we can do about this other than log error
2235 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2236 }
2237
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002238 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002239
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002240 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002241 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002242 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002243 return
2244 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002245 pDevEntry.MutexPersOnuConfig.RLock()
2246 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2247 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002248 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002249 log.Fields{"device-id": dh.DeviceID})
2250 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002251 // reconcilement will be continued after ani config is done
2252 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002253 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002254 // *** should generate UniUnlockStateDone event *****
2255 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002256 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002257 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002258 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002259 dh.runUniLockFsm(ctx, false)
2260 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302261 }
2262}
2263
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002264func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2265 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302266
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002267 if !dh.IsReconciling() {
2268 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002269 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002270 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2271 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002272 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002273 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002274 return
2275 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002276 pDevEntry.MutexPersOnuConfig.Lock()
2277 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2278 pDevEntry.MutexPersOnuConfig.Unlock()
2279 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002280 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002281 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002282 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302283 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002284 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 +00002285 log.Fields{"device-id": dh.DeviceID})
2286 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002287 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302288 }
2289}
2290
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002291func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002292 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002293 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002294
2295 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002296 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002297 ConnStatus: voltha.ConnectStatus_REACHABLE,
2298 OperStatus: voltha.OperStatus_UNKNOWN,
2299 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002300 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002301 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002302 }
2303
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002304 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002305 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002306 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002307
2308 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002309 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002310
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002311 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002312 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002313 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002314 return
2315 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002316 pDevEntry.MutexPersOnuConfig.Lock()
2317 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2318 pDevEntry.MutexPersOnuConfig.Unlock()
2319 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002320 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002321 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002322 }
mpagenko900ee4b2020-10-12 11:56:34 +00002323}
2324
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002325func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002326 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002327 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002328 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002329 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002330 ConnStatus: voltha.ConnectStatus_REACHABLE,
2331 OperStatus: voltha.OperStatus_ACTIVE,
2332 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002333 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002334 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002335 }
2336
dbainbri4d3a0dc2020-12-02 00:33:42 +00002337 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002338 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002339 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002340 _ = dh.deviceReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002341
2342 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002343 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002344
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002345 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002346 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002347 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002348 return
2349 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002350 pDevEntry.MutexPersOnuConfig.Lock()
2351 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2352 pDevEntry.MutexPersOnuConfig.Unlock()
2353 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002354 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002355 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002356 }
mpagenko900ee4b2020-10-12 11:56:34 +00002357}
2358
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002359func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2360 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2361 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
2362 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
2363 DeviceId: dh.DeviceID,
2364 OperStatus: voltha.OperStatus_FAILED,
2365 }); err != nil {
2366 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2367 }
2368}
2369
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002370func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2371 if devEvent == cmn.OmciAniConfigDone {
2372 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002373 // attention: the device reason update is done based on ONU-UNI-Port related activity
2374 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002375 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002376 // 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 +00002377 _ = dh.deviceReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302378 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002379 if dh.IsReconciling() {
2380 go dh.ReconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002381 }
2382 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002383 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002384 // attention: the device reason update is done based on ONU-UNI-Port related activity
2385 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002386 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002387 // 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 +00002388 _ = dh.deviceReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002389 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002390 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302391}
2392
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002393func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002394 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002395 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302396 // attention: the device reason update is done based on ONU-UNI-Port related activity
2397 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302398
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002399 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2400 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002401 // which may be the case from some previous actvity on another UNI Port of the ONU
2402 // or even some previous flow add activity on the same port
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002403 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling())
2404 if dh.IsReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002405 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002406 }
2407 }
2408 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002409 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002410 //not relevant for reconcile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002411 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002412 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302413 }
mpagenkof1fc3862021-02-16 10:09:52 +00002414
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002415 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002416 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002417 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002418 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002419 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002420 }
2421 } else {
2422 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002423 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002424 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302425}
2426
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002427//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
2428func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302429 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002430 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002431 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002432 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002433 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002434 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002435 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002436 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002437 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002438 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002439 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002440 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002441 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002442 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002443 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002444 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002445 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002446 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002447 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002448 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002449 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002450 case cmn.UniEnableStateFailed:
2451 {
2452 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2453 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002454 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002455 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002456 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002457 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002458 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002459 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002460 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002461 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002462 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002463 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002464 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002465 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002466 default:
2467 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002468 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002469 }
2470 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002471}
2472
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002473func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002474 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002475 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302476 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002477 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002478 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002479 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302480 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002481 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002482 if pUniPort == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002483 logger.Warnw(ctx, "OnuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002484 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002485 //store UniPort with the System-PortNumber key
2486 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002487 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002488 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002489 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
2490 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002491 } //error logging already within UniPort method
2492 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002493 logger.Debugw(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002494 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002495 }
2496 }
2497}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002498
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002499func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2500 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002501 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002502 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002503 return
2504 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002505 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002506 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002507 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2508 for _, mgmtEntityID := range pptpInstKeys {
2509 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002510 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002511 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2512 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002513 }
2514 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002515 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002516 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002517 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002518 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2519 for _, mgmtEntityID := range veipInstKeys {
2520 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002521 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002522 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2523 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002524 }
2525 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002526 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002527 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002528 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002529 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2530 for _, mgmtEntityID := range potsInstKeys {
2531 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002532 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002533 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2534 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002535 }
2536 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002537 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002538 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002539 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002540 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002541 return
2542 }
2543
2544 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2545 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2546 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
2547 for i := 0; i < int(uniCnt); i++ {
2548 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
2549 dh.stopFlowMonitoringRoutine[i] = make(chan bool)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002550 }
2551}
2552
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002553// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2554func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002555 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302556 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002557 // with following remark:
2558 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2559 // # load on the core
2560
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002561 // 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 +00002562
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002563 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002564 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002565 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2566 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2567 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2568 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002569 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002570 go func(port *cmn.OnuUniPort) {
khenaidoo7d3c5582021-08-11 18:09:44 -04002571 if err := dh.updatePortStateInCore(ctx, &ic.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002572 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002573 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002574 PortNo: port.PortNo,
2575 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002576 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002577 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 -04002578 }
2579 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002580 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002581 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002582 }
mpagenko3af1f032020-06-10 08:53:41 +00002583 }
2584 }
2585}
2586
2587// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002588func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2589 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002590 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2591 for uniNo, uniPort := range dh.uniEntityMap {
2592 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002593
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002594 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2595 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2596 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2597 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002598 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002599 go func(port *cmn.OnuUniPort) {
khenaidoo7d3c5582021-08-11 18:09:44 -04002600 if err := dh.updatePortStateInCore(ctx, &ic.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002601 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002602 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002603 PortNo: port.PortNo,
2604 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002605 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002606 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 -04002607 }
2608 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002609 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002610 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002611 }
2612
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002613 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002614 }
2615}
2616
2617// ONU_Active/Inactive announcement on system KAFKA bus
2618// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002619func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002620 var de voltha.DeviceEvent
2621 eventContext := make(map[string]string)
2622 //Populating event context
2623 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002624 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002625 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002626 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302627 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002628 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 +00002629 }
2630 oltSerialNumber := parentDevice.SerialNumber
2631
2632 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2633 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2634 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302635 eventContext["olt-serial-number"] = oltSerialNumber
2636 eventContext["device-id"] = aDeviceID
2637 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002638 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002639 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2640 deviceEntry.MutexPersOnuConfig.RLock()
2641 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2642 deviceEntry.MutexPersOnuConfig.RUnlock()
2643 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
2644 deviceEntry.MutexPersOnuConfig.RLock()
2645 eventContext["vendor"] = deviceEntry.SOnuPersistentData.PersVendorID
2646 deviceEntry.MutexPersOnuConfig.RUnlock()
2647 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002648 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2649 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2650 } else {
2651 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2652 log.Fields{"device-id": aDeviceID})
2653 return
2654 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002655
2656 /* Populating device event body */
2657 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302658 de.ResourceId = aDeviceID
2659 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002660 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2661 de.Description = fmt.Sprintf("%s Event - %s - %s",
2662 cEventObjectType, cOnuActivatedEvent, "Raised")
2663 } else {
2664 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2665 de.Description = fmt.Sprintf("%s Event - %s - %s",
2666 cEventObjectType, cOnuActivatedEvent, "Cleared")
2667 }
2668 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002669 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2670 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302671 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002672 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002673 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302674 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002675}
2676
Himani Chawla4d908332020-08-31 12:30:20 +05302677// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002678func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2679 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002680 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302681 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002682 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002683 sFsmName = "LockStateFSM"
2684 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002685 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002686 sFsmName = "UnLockStateFSM"
2687 }
mpagenko3af1f032020-06-10 08:53:41 +00002688
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002689 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002690 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002691 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002692 return
2693 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002694 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002695 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302696 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002697 dh.pLockStateFsm = pLSFsm
2698 } else {
2699 dh.pUnlockStateFsm = pLSFsm
2700 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002701 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002702 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002703 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002704 }
2705}
2706
2707// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002708func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002709 /* Uni Port lock/unlock procedure -
2710 ***** should run via 'adminDone' state and generate the argument requested event *****
2711 */
2712 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302713 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002714 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002715 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2716 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002717 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2718 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002719 }
2720 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002721 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002722 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2723 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002724 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2725 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002726 }
2727 }
2728 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002729 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2730 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002731 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002732 // maybe try a FSM reset and then again ... - TODO!!!
2733 } else {
2734 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002735 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002736 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002737 }
2738 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002739 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002740 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002741 // maybe try a FSM reset and then again ... - TODO!!!
2742 }
2743 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002744 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002745 // maybe try a FSM reset and then again ... - TODO!!!
2746 }
2747}
2748
mpagenko80622a52021-02-09 16:53:23 +00002749// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00002750// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002751func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002752 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002753 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002754 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002755 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002756 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002757 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002758 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002759 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002760 sFsmName, chUpgradeFsm)
2761 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002762 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00002763 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002764 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
2765 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
mpagenko80622a52021-02-09 16:53:23 +00002766 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2767 // maybe try a FSM reset and then again ... - TODO!!!
2768 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2769 }
mpagenko59862f02021-10-11 08:53:18 +00002770 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00002771 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2772 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00002773 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2774 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002775 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002776 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002777 } else {
2778 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002779 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002780 // maybe try a FSM reset and then again ... - TODO!!!
2781 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2782 }
2783 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002784 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002785 // maybe try a FSM reset and then again ... - TODO!!!
2786 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2787 }
2788 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002789 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002790 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2791 }
2792 return nil
2793}
2794
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002795// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
2796func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002797 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002798 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002799 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00002800 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2801 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00002802 dh.pLastUpgradeImageState = apImageState
2803 dh.lockUpgradeFsm.Unlock()
2804 //signal upgradeFsm removed using non-blocking channel send
2805 select {
2806 case dh.upgradeFsmChan <- struct{}{}:
2807 default:
2808 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002809 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00002810 }
mpagenko80622a52021-02-09 16:53:23 +00002811}
2812
mpagenko15ff4a52021-03-02 10:09:20 +00002813// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2814func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002815 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00002816 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002817 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002818 return
2819 }
2820
2821 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00002822 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00002823 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002824 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
2825 dh.lockUpgradeFsm.RUnlock()
2826 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
2827 return
2828 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002829 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00002830 if pUpgradeStatemachine != nil {
2831 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2832 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002833 UpgradeState := pUpgradeStatemachine.Current()
2834 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
2835 (UpgradeState == swupg.UpgradeStRequestingActivate) {
2836 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00002837 // 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 +00002838 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00002839 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
2840 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00002841 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00002842 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002843 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00002844 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2845 dh.upgradeCanceled = true
2846 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2847 }
mpagenko15ff4a52021-03-02 10:09:20 +00002848 return
2849 }
mpagenko59862f02021-10-11 08:53:18 +00002850 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002851 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
2852 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00002853 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002854 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
mpagenko1f8e8822021-06-25 14:10:21 +00002855 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
2856 return
2857 }
2858 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002859 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00002860 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002861 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
2862 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
mpagenko1f8e8822021-06-25 14:10:21 +00002863 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2864 return
2865 }
2866 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002867 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00002868 }
2869 } else {
2870 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 +00002871 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00002872 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2873 dh.upgradeCanceled = true
2874 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2875 }
mpagenko1f8e8822021-06-25 14:10:21 +00002876 }
mpagenko15ff4a52021-03-02 10:09:20 +00002877 return
2878 }
mpagenko59862f02021-10-11 08:53:18 +00002879 dh.lockUpgradeFsm.RUnlock()
2880 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2881 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00002882 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2883 dh.upgradeCanceled = true
2884 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2885 }
mpagenko59862f02021-10-11 08:53:18 +00002886 return
2887 }
2888 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2889 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2890 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2891 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
2892 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2893 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
2894 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00002895 }
mpagenko15ff4a52021-03-02 10:09:20 +00002896 }
2897 }
2898 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002899 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002900 }
mpagenko59862f02021-10-11 08:53:18 +00002901 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00002902}
2903
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002904//SetBackend provides a DB backend for the specified path on the existing KV client
2905func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002906
2907 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002908 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07002909 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00002910 kvbackend := &db.Backend{
2911 Client: dh.pOpenOnuAc.kvClient,
2912 StoreType: dh.pOpenOnuAc.KVStoreType,
2913 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002914 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002915 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2916 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002917
mpagenkoaf801632020-07-03 10:00:42 +00002918 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002919}
khenaidoo7d3c5582021-08-11 18:09:44 -04002920func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302921 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002922
mpagenkodff5dda2020-08-28 11:52:01 +00002923 for _, field := range flow.GetOfbFields(apFlowItem) {
2924 switch field.Type {
2925 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2926 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002927 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002928 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2929 }
mpagenko01e726e2020-10-23 09:45:29 +00002930 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002931 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2932 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302933 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002934 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302935 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2936 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002937 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2938 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002939 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002940 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302941 return
mpagenkodff5dda2020-08-28 11:52:01 +00002942 }
2943 }
mpagenko01e726e2020-10-23 09:45:29 +00002944 */
mpagenkodff5dda2020-08-28 11:52:01 +00002945 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2946 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302947 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002948 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302949 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002950 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302951 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002952 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002953 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302954 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002955 }
2956 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2957 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302958 *loAddPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002959 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002960 "PCP": loAddPcp})
2961 }
2962 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2963 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002964 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002965 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2966 }
2967 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2968 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002969 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002970 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2971 }
2972 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2973 {
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 "IPv4-DST": field.GetIpv4Dst()})
2976 }
2977 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
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 "IPv4-SRC": field.GetIpv4Src()})
2981 }
2982 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
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 "Metadata": field.GetTableMetadata()})
2986 }
2987 /*
2988 default:
2989 {
2990 //all other entires ignored
2991 }
2992 */
2993 }
2994 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302995}
mpagenkodff5dda2020-08-28 11:52:01 +00002996
khenaidoo7d3c5582021-08-11 18:09:44 -04002997func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002998 for _, action := range flow.GetActions(apFlowItem) {
2999 switch action.Type {
3000 /* not used:
3001 case of.OfpActionType_OFPAT_OUTPUT:
3002 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003003 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003004 "Output": action.GetOutput()})
3005 }
3006 */
3007 case of.OfpActionType_OFPAT_PUSH_VLAN:
3008 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003009 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003010 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3011 }
3012 case of.OfpActionType_OFPAT_SET_FIELD:
3013 {
3014 pActionSetField := action.GetSetField()
3015 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003016 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003017 "OxcmClass": pActionSetField.Field.OxmClass})
3018 }
3019 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303020 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003021 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303022 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003023 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303024 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003025 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303026 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003027 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003028 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003029 "Type": pActionSetField.Field.GetOfbField().Type})
3030 }
3031 }
3032 /*
3033 default:
3034 {
3035 //all other entires ignored
3036 }
3037 */
3038 }
3039 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303040}
3041
3042//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003043func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003044 apFlowMetaData *voltha.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303045 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3046 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
3047 var loAddPcp, loSetPcp uint8
3048 var loIPProto uint32
3049 /* the TechProfileId is part of the flow Metadata - compare also comment within
3050 * OLT-Adapter:openolt_flowmgr.go
3051 * Metadata 8 bytes:
3052 * Most Significant 2 Bytes = Inner VLAN
3053 * Next 2 Bytes = Tech Profile ID(TPID)
3054 * Least Significant 4 Bytes = Port ID
3055 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3056 * subscriber related flows.
3057 */
3058
dbainbri4d3a0dc2020-12-02 00:33:42 +00003059 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303060 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003061 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003062 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003063 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303064 }
mpagenko551a4d42020-12-08 18:09:20 +00003065 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003066 loCookie := apFlowItem.GetCookie()
3067 loCookieSlice := []uint64{loCookie}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003068 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003069 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05303070
dbainbri4d3a0dc2020-12-02 00:33:42 +00003071 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003072 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303073 if loIPProto == 2 {
3074 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3075 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003076 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003077 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303078 return nil
3079 }
mpagenko01e726e2020-10-23 09:45:29 +00003080 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003081 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003082
3083 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003084 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003085 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003086 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3087 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3088 //TODO!!: Use DeviceId within the error response to rwCore
3089 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003090 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003091 }
3092 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003093 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003094 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3095 } else {
3096 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3097 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3098 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303099 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003100 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003101 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003102 }
mpagenko9a304ea2020-12-16 15:54:01 +00003103
ozgecanetsia82b91a62021-05-21 18:54:49 +03003104 var meter *voltha.OfpMeterConfig
3105 if apFlowMetaData != nil {
3106 meter = apFlowMetaData.Meters[0]
3107 }
mpagenkobc4170a2021-08-17 16:42:10 +00003108 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3109 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3110 // when different rules are requested concurrently for the same uni
3111 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3112 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3113 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003114 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3115 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003116 //SetUniFlowParams() may block on some rule that is suspended-to-add
3117 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003118 // Also the error is returned to caller via response channel
3119 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
3120 loMatchVlan, loSetVlan, loSetPcp, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003121 dh.lockVlanConfig.RUnlock()
3122 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003123 return
mpagenkodff5dda2020-08-28 11:52:01 +00003124 }
mpagenkobc4170a2021-08-17 16:42:10 +00003125 dh.lockVlanConfig.RUnlock()
3126 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003127 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003128 loMatchVlan, loSetVlan, loSetPcp, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003129 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003130 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003131 if err != nil {
3132 *respChan <- err
3133 }
mpagenko01e726e2020-10-23 09:45:29 +00003134}
3135
3136//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003137func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003138 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3139 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3140 //no extra check is done on the rule parameters
3141 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3142 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3143 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3144 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003145 // - 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 +00003146 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003147 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003148
3149 /* TT related temporary workaround - should not be needed anymore
3150 for _, field := range flow.GetOfbFields(apFlowItem) {
3151 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3152 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003153 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003154 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3155 if loIPProto == 2 {
3156 // 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 +00003157 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003158 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003159 return nil
3160 }
3161 }
3162 } //for all OfbFields
3163 */
3164
mpagenko9a304ea2020-12-16 15:54:01 +00003165 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003166 dh.lockVlanConfig.RLock()
3167 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003168 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3169 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003170 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3171 return
mpagenko01e726e2020-10-23 09:45:29 +00003172 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003173 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003174 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003175 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003176 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003177 // Push response on the response channel
3178 if respChan != nil {
3179 // 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
3180 select {
3181 case *respChan <- nil:
3182 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3183 default:
3184 }
3185 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003186 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003187}
3188
Himani Chawla26e555c2020-08-31 12:30:20 +05303189// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003190// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003191// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003192func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003193 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent cmn.OnuDeviceEvent, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003194 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003195
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003196 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003197 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003198 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3199 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003200 }
3201
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003202 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3203 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003204 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003205 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003206 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3207 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003208 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3209 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003210 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003211 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3212 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003213 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003214 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003215 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303216 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003217 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003218 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3219 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003220 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003221 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003222 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3223 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003224 }
3225 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003226 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003227 "device-id": dh.DeviceID})
3228 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003229 }
3230 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003231 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003232 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3233 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003234 }
3235 return nil
3236}
3237
mpagenkofc4f56e2020-11-04 17:17:49 +00003238//VerifyVlanConfigRequest checks on existence of a given uniPort
3239// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003240func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003241 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003242 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003243 for _, uniPort := range dh.uniEntityMap {
3244 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003245 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003246 pCurrentUniPort = uniPort
3247 break //found - end search loop
3248 }
3249 }
3250 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003251 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003252 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003253 return
3254 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003255 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003256}
3257
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003258//VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
3259func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003260 //TODO!! verify and start pending flow configuration
3261 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3262 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003263
3264 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003265 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003266 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003267 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003268 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003269 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003270 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003271 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003272 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3273 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003274 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003275 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003276 } else {
3277 /***** UniVlanConfigFsm continued */
3278 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003279 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3280 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003281 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003282 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3283 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003284 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003285 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003286 } else {
3287 /***** UniVlanConfigFsm continued */
3288 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003289 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3290 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003291 }
mpagenkodff5dda2020-08-28 11:52:01 +00003292 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003293 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003294 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3295 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003296 }
3297 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003298 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 +00003299 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3300 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003301 }
3302 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003303 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003304 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003305 }
mpagenkof1fc3862021-02-16 10:09:52 +00003306 } else {
3307 dh.lockVlanConfig.RUnlock()
3308 }
mpagenkodff5dda2020-08-28 11:52:01 +00003309}
3310
3311//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3312// 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 +00003313func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003314 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003315 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003316 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003317 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003318 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003319 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003320}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003321
mpagenkof1fc3862021-02-16 10:09:52 +00003322//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003323func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003324 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3325 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3326 // obviously then parallel processing on the cancel must be avoided
3327 // deadline context to ensure completion of background routines waited for
3328 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3329 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3330 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3331
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003332 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003333 var wg sync.WaitGroup
3334 wg.Add(1) // for the 1 go routine to finish
3335
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003336 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003337 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3338
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003339 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003340}
3341
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003342//StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003343//available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003344func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3345 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003346
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003347 if dh.IsReconciling() {
3348 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003349 return nil
3350 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003351 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003352
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003353 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003354 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003355 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3356 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003357 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003358 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003359
mpagenkof1fc3862021-02-16 10:09:52 +00003360 if aWriteToKvStore {
3361 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3362 }
3363 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003364}
3365
dbainbri4d3a0dc2020-12-02 00:33:42 +00003366func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003367 defer cancel() //ensure termination of context (may be pro forma)
3368 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003369 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003370 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003371}
3372
dbainbri4d3a0dc2020-12-02 00:33:42 +00003373func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003374
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003375 dh.SetDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003376 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003377 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo7d3c5582021-08-11 18:09:44 -04003378 if err := dh.updateDeviceReasonInCore(ctx, &ic.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003379 DeviceId: dh.DeviceID,
3380 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003381 }); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003382 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003383 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003384 return err
3385 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003386 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", cmn.DeviceReasonMap[deviceReason], dh.DeviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003387 return nil
3388 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003389 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 +00003390 return nil
3391}
3392
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003393func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3394 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003395 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003396 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3397 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003398 }
mpagenkof1fc3862021-02-16 10:09:52 +00003399 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003400}
3401
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003402// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003403// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003404func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3405 dh.lockDevice.RLock()
3406 defer dh.lockDevice.RUnlock()
3407 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003408 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003409 }
3410 return 0, errors.New("error-fetching-uni-port")
3411}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003412
3413// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003414func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3415 var errorsList []error
3416 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 -08003417
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003418 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3419 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3420 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3421
3422 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3423 // successfully.
3424 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3425 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3426 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003427 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 -08003428 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003429 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003430 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003431 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003432}
3433
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003434func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3435 var err error
3436 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003437 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003438
3439 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003440 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003441 errorsList = append(errorsList, err)
3442 }
3443 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003444 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003445
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003446 return errorsList
3447}
3448
3449func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3450 var err error
3451 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003452 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003453 // Check if group metric related config is updated
3454 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003455 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3456 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3457 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003458
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003459 if ok && m.Frequency != v.GroupFreq {
3460 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003461 errorsList = append(errorsList, err)
3462 }
3463 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003464 if ok && m.Enabled != v.Enabled {
3465 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003466 errorsList = append(errorsList, err)
3467 }
3468 }
3469 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003470 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003471 return errorsList
3472}
3473
3474func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3475 var err error
3476 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003477 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003478 // Check if standalone metric related config is updated
3479 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003480 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3481 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3482 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003483
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003484 if ok && m.Frequency != v.SampleFreq {
3485 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003486 errorsList = append(errorsList, err)
3487 }
3488 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003489 if ok && m.Enabled != v.Enabled {
3490 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003491 errorsList = append(errorsList, err)
3492 }
3493 }
3494 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003495 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003496 return errorsList
3497}
3498
3499// nolint: gocyclo
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003500func (dh *deviceHandler) StartCollector(ctx context.Context) {
Girish Gowdrae09a6202021-01-12 18:10:59 -08003501 logger.Debugf(ctx, "startingCollector")
3502
3503 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003504 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303505 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003506 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003507 // Initialize the next metric collection time.
3508 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3509 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003510 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003511 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003512 for {
3513 select {
3514 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003515 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003516 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003517 // Stop the L2 PM FSM
3518 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003519 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3520 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3521 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003522 }
3523 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003524 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003525 }
3526 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003527 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3528 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003529 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003530 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3531 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003532 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003533
Girish Gowdrae09a6202021-01-12 18:10:59 -08003534 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003535 case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3536 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3537 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3538 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3539 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003540 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003541 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003542 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003543 } else {
3544 if dh.pmConfigs.Grouped { // metrics are managed as a group
3545 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003546 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003547
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003548 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3549 // 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 -08003550 // 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 +00003551 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3552 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003553 }
3554 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003555 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3556 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3557 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3558 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003559 }
3560 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003561 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003562
3563 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003564 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3565 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3566 // 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 -08003567 // 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 +00003568 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3569 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003570 }
3571 }
3572 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003573 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3574 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3575 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3576 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003577 }
3578 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003579 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003580 } /* else { // metrics are not managed as a group
3581 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3582 } */
3583 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003584 }
3585 }
3586}
kesavandfdf77632021-01-26 23:40:33 -05003587
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003588func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003589
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003590 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3591 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003592}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003593
Himani Chawla43f95ff2021-06-03 00:24:12 +05303594func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3595 if dh.pOnuMetricsMgr == nil {
3596 return &extension.SingleGetValueResponse{
3597 Response: &extension.GetValueResponse{
3598 Status: extension.GetValueResponse_ERROR,
3599 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3600 },
3601 }
3602 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303603 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303604 return resp
3605}
3606
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003607func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3608 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003609 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003610 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003611 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003612}
3613
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003614func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003615 var pAdapterFsm *cmn.AdapterFsm
3616 //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 +00003617 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003618 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003619 {
mpagenkofbf577d2021-10-12 11:44:33 +00003620 if dh.pOnuOmciDevice != nil {
3621 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3622 } else {
3623 return true //FSM not active - so there is no activity on omci
3624 }
mpagenkof1fc3862021-02-16 10:09:52 +00003625 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003626 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003627 {
mpagenkofbf577d2021-10-12 11:44:33 +00003628 if dh.pOnuOmciDevice != nil {
3629 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3630 } else {
3631 return true //FSM not active - so there is no activity on omci
3632 }
mpagenkof1fc3862021-02-16 10:09:52 +00003633 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003634 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003635 {
mpagenkofbf577d2021-10-12 11:44:33 +00003636 if dh.pLockStateFsm != nil {
3637 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3638 } else {
3639 return true //FSM not active - so there is no activity on omci
3640 }
mpagenkof1fc3862021-02-16 10:09:52 +00003641 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003642 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003643 {
mpagenkofbf577d2021-10-12 11:44:33 +00003644 if dh.pUnlockStateFsm != nil {
3645 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3646 } else {
3647 return true //FSM not active - so there is no activity on omci
3648 }
mpagenkof1fc3862021-02-16 10:09:52 +00003649 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003650 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003651 {
mpagenkofbf577d2021-10-12 11:44:33 +00003652 if dh.pOnuMetricsMgr != nil {
3653 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003654 } else {
3655 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003656 }
3657 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003658 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003659 {
3660 dh.lockUpgradeFsm.RLock()
3661 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003662 if dh.pOnuUpradeFsm != nil {
3663 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3664 } else {
3665 return true //FSM not active - so there is no activity on omci
3666 }
mpagenko80622a52021-02-09 16:53:23 +00003667 }
mpagenkof1fc3862021-02-16 10:09:52 +00003668 default:
3669 {
3670 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003671 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003672 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003673 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003674 }
mpagenkofbf577d2021-10-12 11:44:33 +00003675 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3676 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3677 }
3678 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003679}
3680
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003681func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3682 for _, v := range dh.pOnuTP.PAniConfigFsm {
3683 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003684 return false
3685 }
3686 }
3687 return true
3688}
3689
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003690func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003691 dh.lockVlanConfig.RLock()
3692 defer dh.lockVlanConfig.RUnlock()
3693 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003694 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003695 return false
3696 }
3697 }
3698 return true //FSM not active - so there is no activity on omci
3699}
3700
3701func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3702 dh.lockVlanConfig.RLock()
3703 defer dh.lockVlanConfig.RUnlock()
3704 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003705 if v.PAdaptFsm.PFsm != nil {
3706 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003707 return true //there is at least one VLAN FSM with some active configuration
3708 }
3709 }
3710 }
3711 return false //there is no VLAN FSM with some active configuration
3712}
3713
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003714func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003715 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3716 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3717 return false
3718 }
3719 }
3720 // a further check is done to identify, if at least some data traffic related configuration exists
3721 // 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])
3722 return dh.checkUserServiceExists(ctx)
3723}
3724
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003725func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003726 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3727 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003728 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003729 // TODO: fatal error reset ONU, delete deviceHandler!
3730 return
3731 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003732 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
3733 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003734}
3735
3736func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3737 dh.mutexCollectorFlag.Lock()
3738 dh.collectorIsRunning = flagValue
3739 dh.mutexCollectorFlag.Unlock()
3740}
3741
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003742func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003743 dh.mutexCollectorFlag.RLock()
3744 flagValue := dh.collectorIsRunning
3745 dh.mutexCollectorFlag.RUnlock()
3746 return flagValue
3747}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303748
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303749func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3750 dh.mutextAlarmManagerFlag.Lock()
3751 dh.alarmManagerIsRunning = flagValue
3752 dh.mutextAlarmManagerFlag.Unlock()
3753}
3754
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003755func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303756 dh.mutextAlarmManagerFlag.RLock()
3757 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303758 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303759 dh.mutextAlarmManagerFlag.RUnlock()
3760 return flagValue
3761}
3762
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003763func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303764 logger.Debugf(ctx, "startingAlarmManager")
3765
3766 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003767 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303768 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303769 if stop := <-dh.stopAlarmManager; stop {
3770 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303771 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303772 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003773 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
3774 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05303775 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303776 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003777 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
3778 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05303779 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303780 }
3781}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003782
Girish Gowdrae95687a2021-09-08 16:30:58 -07003783func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
3784 dh.mutexFlowMonitoringRoutineFlag.Lock()
3785 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
3786 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"flag": flag})
3787 dh.isFlowMonitoringRoutineActive[uniID] = flag
3788}
3789
3790func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
3791 dh.mutexFlowMonitoringRoutineFlag.RLock()
3792 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
3793 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
3794 log.Fields{"isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
3795 return dh.isFlowMonitoringRoutineActive[uniID]
3796}
3797
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003798func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
3799 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003800
Maninder7961d722021-06-16 22:10:28 +05303801 connectStatus := voltha.ConnectStatus_UNREACHABLE
3802 operState := voltha.OperStatus_UNKNOWN
3803
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003804 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003805 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003806 logger.Debugw(ctx, "wait for channel signal or timeout",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003807 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003808 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003809 case success := <-dh.chReconcilingFinished:
3810 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003811 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05303812 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003813 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05303814 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003815 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05303816 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003817 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
3818 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05303819 operState = voltha.OperStatus_ACTIVE
3820 } else {
3821 operState = voltha.OperStatus_ACTIVATING
3822 }
3823 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003824 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
3825 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
3826 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05303827 operState = voltha.OperStatus_DISCOVERED
3828 }
3829
3830 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303831 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003832 logger.Debugw(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003833 log.Fields{"device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04003834 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003835 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003836 ConnStatus: connectStatus,
3837 OperStatus: operState,
3838 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05303839 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003840 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05303841 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003842 } else {
Maninderb5187552021-03-23 22:23:42 +05303843 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003844 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05303845
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003846 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05303847 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003848 log.Fields{"device-id": dh.DeviceID})
3849 } else if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninder7961d722021-06-16 22:10:28 +05303850 connectStatus = voltha.ConnectStatus_REACHABLE
3851 }
3852
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003853 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003854 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003855 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003856 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003857 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05303858
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003859 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05303860 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003861 log.Fields{"device-id": dh.DeviceID})
3862 } else if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninder7961d722021-06-16 22:10:28 +05303863 connectStatus = voltha.ConnectStatus_REACHABLE
3864 }
3865
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003866 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05303867
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003868 }
3869 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003870 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003871 dh.mutexReconcilingFlag.Unlock()
3872 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003873 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003874 dh.mutexReconcilingFlag.Lock()
3875 if skipOnuConfig {
3876 dh.reconciling = cSkipOnuConfigReconciling
3877 } else {
3878 dh.reconciling = cOnuConfigReconciling
3879 }
3880 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003881}
3882
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003883func (dh *deviceHandler) StopReconciling(ctx context.Context, success bool) {
3884 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
3885 if dh.IsReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07003886 dh.chReconcilingFinished <- success
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003887 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003888 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003889 }
3890}
3891
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003892func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003893 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003894 defer dh.mutexReconcilingFlag.RUnlock()
3895 return dh.reconciling != cNoReconciling
3896}
3897
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003898func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003899 dh.mutexReconcilingFlag.RLock()
3900 defer dh.mutexReconcilingFlag.RUnlock()
3901 return dh.reconciling == cSkipOnuConfigReconciling
3902}
3903
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003904func (dh *deviceHandler) SetDeviceReason(value uint8) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003905 dh.mutexDeviceReason.Lock()
3906 dh.deviceReason = value
3907 dh.mutexDeviceReason.Unlock()
3908}
3909
3910func (dh *deviceHandler) getDeviceReason() uint8 {
3911 dh.mutexDeviceReason.RLock()
3912 value := dh.deviceReason
3913 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003914 return value
3915}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003916
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003917func (dh *deviceHandler) GetDeviceReasonString() string {
3918 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003919}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003920
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003921func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003922 dh.mutexReadyForOmciConfig.Lock()
3923 dh.readyForOmciConfig = flagValue
3924 dh.mutexReadyForOmciConfig.Unlock()
3925}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003926func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003927 dh.mutexReadyForOmciConfig.RLock()
3928 flagValue := dh.readyForOmciConfig
3929 dh.mutexReadyForOmciConfig.RUnlock()
3930 return flagValue
3931}
Maninder7961d722021-06-16 22:10:28 +05303932
3933func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
3934 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
3935 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003936 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05303937 }
3938
3939 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo7d3c5582021-08-11 18:09:44 -04003940 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003941 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003942 ConnStatus: connectStatus,
3943 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
3944 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05303945 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003946 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05303947 }
3948}
khenaidoo7d3c5582021-08-11 18:09:44 -04003949
3950/*
3951Helper functions to communicate with Core
3952*/
3953
3954func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
3955 cClient, err := dh.coreClient.GetCoreServiceClient()
3956 if err != nil || cClient == nil {
3957 return nil, err
3958 }
3959 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3960 defer cancel()
3961 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
3962 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
3963}
3964
3965func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ic.DeviceStateFilter) error {
3966 cClient, err := dh.coreClient.GetCoreServiceClient()
3967 if err != nil || cClient == nil {
3968 return err
3969 }
3970 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3971 defer cancel()
3972 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
3973 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-state": deviceStateFilter, "error": err})
3974 return err
3975}
3976
3977func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3978 cClient, err := dh.coreClient.GetCoreServiceClient()
3979 if err != nil || cClient == nil {
3980 return err
3981 }
3982 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3983 defer cancel()
3984 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
3985 logger.Debugw(subCtx, "pmconfig-updated-in-core", log.Fields{"pm-configs": pmConfigs, "error": err})
3986 return err
3987}
3988
3989func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
3990 cClient, err := dh.coreClient.GetCoreServiceClient()
3991 if err != nil || cClient == nil {
3992 return err
3993 }
3994 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3995 defer cancel()
3996 _, err = cClient.DeviceUpdate(subCtx, device)
3997 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
3998 return err
3999}
4000
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004001func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004002 cClient, err := dh.coreClient.GetCoreServiceClient()
4003 if err != nil || cClient == nil {
4004 return err
4005 }
4006 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4007 defer cancel()
4008 _, err = cClient.PortCreated(subCtx, port)
4009 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4010 return err
4011}
4012
4013func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ic.PortState) error {
4014 cClient, err := dh.coreClient.GetCoreServiceClient()
4015 if err != nil || cClient == nil {
4016 return err
4017 }
4018 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4019 defer cancel()
4020 _, err = cClient.PortStateUpdate(subCtx, portState)
4021 logger.Debugw(subCtx, "port-state-updated-in-core", log.Fields{"port-state": portState, "error": err})
4022 return err
4023}
4024
4025func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ic.DeviceReason) error {
4026 cClient, err := dh.coreClient.GetCoreServiceClient()
4027 if err != nil || cClient == nil {
4028 return err
4029 }
4030 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4031 defer cancel()
4032 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
4033 logger.Debugw(subCtx, "device-reason-updated-in-core", log.Fields{"reason": reason, "error": err})
4034 return err
4035}
4036
4037/*
4038Helper functions to communicate with parent adapter
4039*/
4040
4041func (dh *deviceHandler) getTechProfileInstanceFromParentAdapter(ctx context.Context, parentEndpoint string,
4042 request *ic.TechProfileInstanceRequestMessage) (*ic.TechProfileDownloadMessage, error) {
4043 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4044 if err != nil || pgClient == nil {
4045 return nil, err
4046 }
4047 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4048 defer cancel()
4049 logger.Debugw(subCtx, "get-tech-profile-instance", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4050 return pgClient.GetTechProfileInstance(subCtx, request)
4051}
4052
Girish Gowdrae95687a2021-09-08 16:30:58 -07004053// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4054// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4055func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4056 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4057 dh.setFlowMonitoringIsRunning(uniID, true)
4058 for {
4059 select {
4060 // block on the channel to receive an incoming flow
4061 // process the flow completely before proceeding to handle the next flow
4062 case flowCb := <-dh.flowCbChan[uniID]:
4063 startTime := time.Now()
4064 logger.Debugw(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
4065 respChan := make(chan error)
4066 if flowCb.addFlow {
4067 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4068 } else {
4069 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4070 }
4071 // Block on response and tunnel it back to the caller
4072 *flowCb.respChan <- <-respChan
4073 logger.Debugw(flowCb.ctx, "serial-flow-processor--end",
4074 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4075 case <-dh.stopFlowMonitoringRoutine[uniID]:
4076 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4077 dh.setFlowMonitoringIsRunning(uniID, false)
4078 return
4079 }
4080 }
4081}
4082
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004083func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ic.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004084 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4085 if err != nil || pgClient == nil {
4086 return err
4087 }
4088 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4089 defer cancel()
4090 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4091 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4092 if err != nil {
4093 logger.Errorw(ctx, "omci-failure", log.Fields{"request": request, "error": err, "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
4094 }
4095 return err
4096}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004097
4098// GetDeviceID - TODO: add comment
4099func (dh *deviceHandler) GetDeviceID() string {
4100 return dh.DeviceID
4101}
4102
4103// GetProxyAddressID - TODO: add comment
4104func (dh *deviceHandler) GetProxyAddressID() string {
4105 return dh.device.ProxyAddress.GetDeviceId()
4106}
4107
4108// GetProxyAddressType - TODO: add comment
4109func (dh *deviceHandler) GetProxyAddressType() string {
4110 return dh.device.ProxyAddress.GetDeviceType()
4111}
4112
4113// GetProxyAddress - TODO: add comment
4114func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4115 return dh.device.ProxyAddress
4116}
4117
4118// GetEventProxy - TODO: add comment
4119func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4120 return dh.EventProxy
4121}
4122
4123// GetOmciTimeout - TODO: add comment
4124func (dh *deviceHandler) GetOmciTimeout() int {
4125 return dh.pOpenOnuAc.omciTimeout
4126}
4127
4128// GetAlarmAuditInterval - TODO: add comment
4129func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4130 return dh.pOpenOnuAc.alarmAuditInterval
4131}
4132
4133// GetDlToOnuTimeout4M - TODO: add comment
4134func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4135 return dh.pOpenOnuAc.dlToOnuTimeout4M
4136}
4137
4138// GetUniEntityMap - TODO: add comment
4139func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4140 return &dh.uniEntityMap
4141}
4142
4143// GetPonPortNumber - TODO: add comment
4144func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4145 return &dh.ponPortNumber
4146}
4147
4148// GetUniVlanConfigFsm - TODO: add comment
4149func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004150 dh.lockVlanConfig.RLock()
4151 value := dh.UniVlanConfigFsmMap[uniID]
4152 dh.lockVlanConfig.RUnlock()
4153 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004154}
4155
4156// GetOnuAlarmManager - TODO: add comment
4157func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4158 return dh.pAlarmMgr
4159}
4160
4161// GetOnuMetricsManager - TODO: add comment
4162func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4163 return dh.pOnuMetricsMgr
4164}
4165
4166// GetOnuTP - TODO: add comment
4167func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4168 return dh.pOnuTP
4169}
4170
4171// GetBackendPathPrefix - TODO: add comment
4172func (dh *deviceHandler) GetBackendPathPrefix() string {
4173 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4174}
4175
4176// GetOnuIndication - TODO: add comment
4177func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4178 return dh.pOnuIndication
4179}
4180
4181// RLockMutexDeletionInProgressFlag - TODO: add comment
4182func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4183 dh.mutexDeletionInProgressFlag.RLock()
4184}
4185
4186// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4187func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4188 dh.mutexDeletionInProgressFlag.RUnlock()
4189}
4190
4191// GetDeletionInProgress - TODO: add comment
4192func (dh *deviceHandler) GetDeletionInProgress() bool {
4193 return dh.deletionInProgress
4194}
4195
4196// GetPmConfigs - TODO: add comment
4197func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4198 return dh.pmConfigs
4199}
4200
4201// GetDeviceType - TODO: add comment
4202func (dh *deviceHandler) GetDeviceType() string {
4203 return dh.DeviceType
4204}
4205
4206// GetLogicalDeviceID - TODO: add comment
4207func (dh *deviceHandler) GetLogicalDeviceID() string {
4208 return dh.logicalDeviceID
4209}
4210
4211// GetDevice - TODO: add comment
4212func (dh *deviceHandler) GetDevice() *voltha.Device {
4213 return dh.device
4214}
4215
4216// GetMetricsEnabled - TODO: add comment
4217func (dh *deviceHandler) GetMetricsEnabled() bool {
4218 return dh.pOpenOnuAc.MetricsEnabled
4219}
4220
4221// InitPmConfigs - TODO: add comment
4222func (dh *deviceHandler) InitPmConfigs() {
4223 dh.pmConfigs = &voltha.PmConfigs{}
4224}
4225
4226// GetUniPortMask - TODO: add comment
4227func (dh *deviceHandler) GetUniPortMask() int {
4228 return dh.pOpenOnuAc.config.UniPortMask
4229}