blob: d1bd5c1da7ee0d8fd7275f2181690befb5b3e33a [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 {
mpagenko0f543222021-11-03 16:24:14 +0000425 logger.Infow(ctx, "delete-gem-port-request start", 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
mpagenko0f543222021-11-03 16:24:14 +0000437 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
438 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
439 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000440 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000441 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000442 }
443 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000444 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800445 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000446 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
447 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800448 return err
449 }
mpagenko0f543222021-11-03 16:24:14 +0000450 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
451 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000452 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000453
Mahir Gunyel9545be22021-07-04 15:53:16 -0700454 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000455 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000456
Himani Chawla26e555c2020-08-31 12:30:20 +0530457}
458
khenaidoo7d3c5582021-08-11 18:09:44 -0400459func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ic.DeleteTcontMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000460 logger.Infow(ctx, "delete-tcont-request start", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000461
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000462 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000463 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000464 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
465 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000466 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530467 if dh.pOnuTP == nil {
468 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000469 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000470 log.Fields{"device-id": dh.DeviceID})
471 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530472 }
473
Himani Chawla26e555c2020-08-31 12:30:20 +0530474 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000475 dh.pOnuTP.LockTpProcMutex()
476 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000477
mpagenko0f543222021-11-03 16:24:14 +0000478 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
479 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
480 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000481 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000482 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000483 }
484 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700485 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000486 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800487 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000488 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
489 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800490 return err
491 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000492 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 +0000493
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000494 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530495
Mahir Gunyel9545be22021-07-04 15:53:16 -0700496 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000497 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000498
Mahir Gunyel9545be22021-07-04 15:53:16 -0700499}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000500
Mahir Gunyel9545be22021-07-04 15:53:16 -0700501func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000502 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
503 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700504 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000505 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
506 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530507 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700508 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000509 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700510 resourceName = "Gem"
511 } else {
512 resourceName = "Tcont"
513 }
514
515 // deadline context to ensure completion of background routines waited for
516 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
517 dctx, cancel := context.WithDeadline(context.Background(), deadline)
518
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000519 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700520
521 var wg sync.WaitGroup
522 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000523 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700524 resource, entryID, &wg)
525 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000526 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
527 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700528 return err
529 }
530
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000531 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
532 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
533 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
534 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700535 var wg2 sync.WaitGroup
536 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
537 wg2.Add(1)
538 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000539 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
540 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700541 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000542 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
543 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700544 return err
545 }
546 }
547 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000548 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700549 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530550 return nil
551}
552
mpagenkodff5dda2020-08-28 11:52:01 +0000553//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000554func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400555 apOfFlowChanges *of.FlowChanges,
556 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700557 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
558 var errorsList []error
559 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000560 //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 +0000561 if apOfFlowChanges.ToRemove != nil {
562 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000563 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000564 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000565 "device-id": dh.DeviceID})
566 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700567 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000568 continue
569 }
570 flowInPort := flow.GetInPort(flowItem)
571 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000572 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
573 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700574 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000575 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000576 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000577 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000578 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000579 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000580 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000581 continue
582 } else {
583 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000584 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000585 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
586 loUniPort = uniPort
587 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000588 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000589 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000590 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000591 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700592 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000593 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000594 }
595 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000596 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000597 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
598 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700599
600 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
601 // Step1 : Fill flowControlBlock
602 // Step2 : Push the flowControlBlock to ONU channel
603 // Step3 : Wait on response channel for response
604 // Step4 : Return error value
605 startTime := time.Now()
606 respChan := make(chan error)
607 flowCb := FlowCb{
608 ctx: ctx,
609 addFlow: false,
610 flowItem: flowItem,
611 flowMetaData: nil,
612 uniPort: loUniPort,
613 respChan: &respChan,
614 }
615 dh.flowCbChan[loUniPort.UniID] <- flowCb
616 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
617 // Wait on the channel for flow handlers return value
618 retError = <-respChan
619 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
620 if retError != nil {
621 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
622 log.Fields{"device-id": dh.DeviceID, "error": retError})
623 errorsList = append(errorsList, retError)
624 continue
625 }
626 } else {
627 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
628 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000629 }
630 }
631 }
632 }
mpagenko01e726e2020-10-23 09:45:29 +0000633 if apOfFlowChanges.ToAdd != nil {
634 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
635 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000636 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000637 "device-id": dh.DeviceID})
638 retError = fmt.Errorf("flow-add no cookie, 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
641 }
642 flowInPort := flow.GetInPort(flowItem)
643 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000644 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
645 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700646 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000647 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000648 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000649 } else if flowInPort == dh.ponPortNumber {
650 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000651 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000652 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000653 continue
654 } else {
655 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000656 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000657 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
658 loUniPort = uniPort
659 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000660 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000661 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000662 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000663 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700664 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000665 continue
mpagenko01e726e2020-10-23 09:45:29 +0000666 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000667 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
668 // if not, we just throw some error here to have an indication about that, if we really need to support that
669 // then we would need to create some means to activate the internal stored flows
670 // after the device gets active automatically (and still with its dependency to the TechProfile)
671 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
672 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000673 if !dh.IsReadyForOmciConfig() {
674 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
675 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700676 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
677 errorsList = append(errorsList, retError)
678 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000679 }
680
mpagenko01e726e2020-10-23 09:45:29 +0000681 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000682 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000683 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
684 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700685 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
686 // Step1 : Fill flowControlBlock
687 // Step2 : Push the flowControlBlock to ONU channel
688 // Step3 : Wait on response channel for response
689 // Step4 : Return error value
690 startTime := time.Now()
691 respChan := make(chan error)
692 flowCb := FlowCb{
693 ctx: ctx,
694 addFlow: true,
695 flowItem: flowItem,
696 flowMetaData: apFlowMetaData,
697 uniPort: loUniPort,
698 respChan: &respChan,
699 }
700 dh.flowCbChan[loUniPort.UniID] <- flowCb
701 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
702 // Wait on the channel for flow handlers return value
703 retError = <-respChan
704 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
705 if retError != nil {
706 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
707 log.Fields{"device-id": dh.DeviceID, "error": retError})
708 errorsList = append(errorsList, retError)
709 continue
710 }
711 } else {
712 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
713 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000714 }
715 }
716 }
717 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700718 if len(errorsList) > 0 {
719 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
720 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
721 }
722 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000723}
724
Himani Chawla6d2ae152020-09-02 13:11:20 +0530725//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000726//following are the expected device states after this activity:
727//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
728// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000729func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
730 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000731
mpagenko900ee4b2020-10-12 11:56:34 +0000732 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000733 //note that disableDevice sequences in some 'ONU active' state may yield also
734 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000735 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000736 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000737 //disable-device shall be just a UNi/ONU-G related admin state setting
738 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000739
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000740 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000741 // disable UNI ports/ONU
742 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
743 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000744 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000745 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000746 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000747 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000748 }
749 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000750 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000751 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -0400752 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000753 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -0400754 ConnStatus: voltha.ConnectStatus_REACHABLE,
755 OperStatus: voltha.OperStatus_UNKNOWN,
756 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000757 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000758 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000759 }
mpagenko01e726e2020-10-23 09:45:29 +0000760 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000761
762 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000763 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000764 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300765 }
766}
767
Himani Chawla6d2ae152020-09-02 13:11:20 +0530768//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000769func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
770 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000771
mpagenkoaa3afe92021-05-21 16:20:58 +0000772 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000773 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
774 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
775 // for real ONU's that should have nearly no influence
776 // Note that for real ONU's there is anyway a problematic situation with following sequence:
777 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
778 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
779 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000780 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000781
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000782 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000783 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000784 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000785 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000786 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000787 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000788 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000789 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300790}
791
dbainbri4d3a0dc2020-12-02 00:33:42 +0000792func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000793 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000794
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000795 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000796 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000797 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000798 return
799 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000800 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000801 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000802 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000803 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000804 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000805 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000806 dh.StopReconciling(ctx, false)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000807 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000808 }
Himani Chawla4d908332020-08-31 12:30:20 +0530809 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000810 pDevEntry.MutexPersOnuConfig.RLock()
811 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
812 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
813 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
814 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
815 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000816 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000817}
818
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000819func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) {
820 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000821
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000822 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000823 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000824 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
825 if !dh.IsSkipOnuConfigReconciling() {
826 dh.StopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000827 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000828 return
829 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000830 dh.pOnuTP.LockTpProcMutex()
831 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000832
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000833 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000834 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000835 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
836 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000837 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000838 log.Fields{"device-id": dh.DeviceID})
839 if !dh.IsSkipOnuConfigReconciling() {
840 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000841 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000842 return
843 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000844 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700845 techProfsFound := false
846 techProfInstLoadFailed := false
847outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000848 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000849 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
850 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000851 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000852 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000853 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000854 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000855 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
856 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000857 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000858 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000859 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700860 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800861 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700862 // Request the TpInstance again from the openolt adapter in case of reconcile
khenaidoo7d3c5582021-08-11 18:09:44 -0400863 iaTechTpInst, err := dh.getTechProfileInstanceFromParentAdapter(ctx,
864 dh.device.ProxyAddress.AdapterEndpoint,
865 &ic.TechProfileInstanceRequestMessage{
866 DeviceId: dh.device.Id,
867 TpInstancePath: uniData.PersTpPathMap[tpID],
868 ParentDeviceId: dh.parentID,
869 ParentPonPort: dh.device.ParentPortNo,
870 OnuId: dh.device.ProxyAddress.OnuId,
871 UniId: uint32(uniData.PersUniID),
872 })
Girish Gowdra50e56422021-06-01 16:46:04 -0700873 if err != nil || iaTechTpInst == nil {
874 logger.Errorw(ctx, "error fetching tp instance",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000875 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 -0700876 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
877 break outerLoop
878 }
879 var tpInst tech_profile.TechProfileInstance
880 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400881 case *ic.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700882 tpInst = *techTpInst.TpInstance
mpagenko2dc896e2021-08-02 12:03:59 +0000883 logger.Debugw(ctx, "received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000884 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700885 default: // do not support epon or other tech
mpagenko2dc896e2021-08-02 12:03:59 +0000886 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000887 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700888 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
889 break outerLoop
890 }
891
Girish Gowdra041dcb32020-11-16 16:54:30 -0800892 // deadline context to ensure completion of background routines waited for
893 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
894 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000895 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000896
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000897 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800898 var wg sync.WaitGroup
899 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000900 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000901 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000902 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
903 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700904 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
905 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800906 }
mpagenko2dc896e2021-08-02 12:03:59 +0000907 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000908 if len(uniData.PersFlowParams) != 0 {
909 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000910 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000911 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000912 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000913 } // for all UNI entries from SOnuPersistentData
914 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
915 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000916 }
mpagenko2dc896e2021-08-02 12:03:59 +0000917
918 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
919 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
920}
921
922func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
923 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
924 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000925 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000926 log.Fields{"device-id": dh.DeviceID})
927 if !dh.IsSkipOnuConfigReconciling() {
928 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000929 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000930 return
931 }
mpagenko2dc896e2021-08-02 12:03:59 +0000932 if abTechProfInstLoadFailed {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000933 dh.SetDeviceReason(cmn.DrTechProfileConfigDownloadFailed)
934 dh.StopReconciling(ctx, false)
Girish Gowdra50e56422021-06-01 16:46:04 -0700935 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000936 } else if dh.IsSkipOnuConfigReconciling() {
937 dh.SetDeviceReason(cmn.DrTechProfileConfigDownloadSuccess)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000938 }
mpagenko2dc896e2021-08-02 12:03:59 +0000939 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000940 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000941 log.Fields{"device-id": dh.DeviceID})
942 if !dh.IsSkipOnuConfigReconciling() {
943 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000944 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000945 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000946}
947
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000948func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
949 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000950
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000951 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000952 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000953 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
954 if !dh.IsSkipOnuConfigReconciling() {
955 dh.StopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000956 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000957 return
958 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000959
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000960 pDevEntry.MutexPersOnuConfig.RLock()
961 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
962 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000963 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000964 log.Fields{"device-id": dh.DeviceID})
965 if !dh.IsSkipOnuConfigReconciling() {
966 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000967 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000968 return
969 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000970 flowsFound := false
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000971 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000972 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
973 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000974 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000975 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000976 continue
977 }
978 if len(uniData.PersTpPathMap) == 0 {
979 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000980 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000981 // It doesn't make sense to configure any flows if no TPs are available
982 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000983 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000984 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
985 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000986 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000987 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000988
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000989 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000990 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -0700991 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000992 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000993 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
994 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
995 if !dh.IsSkipOnuConfigReconciling() {
996 dh.StopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000997 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000998 return
999 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001000 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001001 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001002 flowsProcessed := 0
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001003 pDevEntry.SetReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001004 for _, flowData := range uniData.PersFlowParams {
mpagenko2dc896e2021-08-02 12:03:59 +00001005 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001006 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001007 if flowsProcessed == len(uniData.PersFlowParams)-1 {
1008 lastFlowToReconcile = true
1009 }
mpagenko01e726e2020-10-23 09:45:29 +00001010 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenko7d14de12021-07-27 08:31:56 +00001011 dh.lockVlanConfig.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001012 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001013 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +00001014 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Girish Gowdrae95687a2021-09-08 16:30:58 -07001015 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter, nil); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001016 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001017 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001018 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001019 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00001020 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Girish Gowdrae95687a2021-09-08 16:30:58 -07001021 uint8(flowData.VlanRuleParams.SetPcp), cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001022 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001023 }
1024 }
mpagenko7d14de12021-07-27 08:31:56 +00001025 dh.lockVlanConfig.Unlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001026 flowsProcessed++
mpagenko2dc896e2021-08-02 12:03:59 +00001027 } //for all flows of this UNI
1028 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001029 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID, "flowsProcessed": flowsProcessed,
1030 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1031 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001032 // this can't be used as global finished reconciling flag because
1033 // assumes is getting called before the state machines for the last flow is completed,
1034 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001035 //dh.SetReconcilingFlows(false)
1036 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1037 } // for all UNI entries from SOnuPersistentData
1038 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001039
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001040 if !flowsFound {
1041 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001042 log.Fields{"device-id": dh.DeviceID})
1043 if !dh.IsSkipOnuConfigReconciling() {
1044 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001045 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001046 return
1047 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001048 if dh.IsSkipOnuConfigReconciling() {
1049 dh.SetDeviceReason(cmn.DrOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001050 }
1051}
1052
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001053func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001054 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.DeviceID})
1055 dh.StopReconciling(ctx, true)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001056}
1057
dbainbri4d3a0dc2020-12-02 00:33:42 +00001058func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001059 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001060
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001061 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001062 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001063 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001064 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001065 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001066 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001067
1068 // deadline context to ensure completion of background routines waited for
1069 //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 +05301070 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001071 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001072
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001073 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001074
1075 var wg sync.WaitGroup
1076 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001077 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001078 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001079
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001080 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001081 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001082}
1083
mpagenko15ff4a52021-03-02 10:09:20 +00001084//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1085// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001086// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001087//was and is called in background - error return does not make sense
1088func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001089 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001090 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001091 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001092 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001093 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001094 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301095 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001096 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001097 return
Himani Chawla4d908332020-08-31 12:30:20 +05301098 }
mpagenko01e726e2020-10-23 09:45:29 +00001099
1100 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001101 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001102
dbainbri4d3a0dc2020-12-02 00:33:42 +00001103 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001104 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001105 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001106 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001107 ConnStatus: voltha.ConnectStatus_REACHABLE,
1108 OperStatus: voltha.OperStatus_DISCOVERED,
1109 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001110 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001111 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001112 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001113 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001114 if err := dh.deviceReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001115 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001116 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001117 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001118 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1119 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1120 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1121 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001122}
1123
mpagenkoc8bba412021-01-15 15:38:44 +00001124//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001125// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001126func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001127 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001128 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001129 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001130
1131 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001132 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001133 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001134 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1135 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001136 }
1137
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001138 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001139 var inactiveImageID uint16
1140 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1141 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001142 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1143 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001144 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001145 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001146 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001147 if err == nil {
1148 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1149 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001150 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001151 }
1152 } else {
1153 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001154 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001155 }
mpagenko15ff4a52021-03-02 10:09:20 +00001156 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001157 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001158 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001159 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1160 dh.upgradeCanceled = true
1161 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1162 }
mpagenko38662d02021-08-11 09:45:19 +00001163 //no effort spent anymore for the old API to automatically cancel and restart the download
1164 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001165 }
mpagenko15ff4a52021-03-02 10:09:20 +00001166 } else {
1167 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001168 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001169 }
1170 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001171 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1172 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001173 }
1174 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001175}
1176
mpagenkoc26d4c02021-05-06 14:27:57 +00001177//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1178// after the OnuImage has been downloaded to the adapter, called in background
1179func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001180 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001181
1182 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001183 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001184 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001185 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001186 return
1187 }
1188
1189 var inactiveImageID uint16
1190 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1191 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001192 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001193
mpagenko59862f02021-10-11 08:53:18 +00001194 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001195 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001196 // but must be still locked at calling createOnuUpgradeFsm
1197 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1198 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1199 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001200 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1201 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001202 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001203 //flush the remove upgradeFsmChan channel
1204 select {
1205 case <-dh.upgradeFsmChan:
1206 logger.Debug(ctx, "flushed-upgrade-fsm-channel")
1207 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001208 }
mpagenko59862f02021-10-11 08:53:18 +00001209 dh.lockUpgradeFsm.Unlock()
1210 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1211 dh.upgradeCanceled = true
1212 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1213 }
mpagenko38662d02021-08-11 09:45:19 +00001214 select {
1215 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001216 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001217 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1218 return
1219 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001220 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001221 }
mpagenko59862f02021-10-11 08:53:18 +00001222 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001223 }
mpagenko38662d02021-08-11 09:45:19 +00001224
1225 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001226 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001227 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001228 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001229 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001230 if err == nil {
1231 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1232 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1233 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001234 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001235 return
1236 }
mpagenko38662d02021-08-11 09:45:19 +00001237 } else {
1238 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001239 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001240 }
1241 return
1242 }
1243 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001244 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001245}
1246
1247//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001248func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1249 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001250 var err error
1251 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1252 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1253 // 2.) activation of the inactive image
1254
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001255 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001256 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001257 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1258 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001259 }
1260 dh.lockUpgradeFsm.RLock()
1261 if dh.pOnuUpradeFsm != nil {
1262 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001263 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001264 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001265 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1266 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001267 }
mpagenko59862f02021-10-11 08:53:18 +00001268 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1269 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1270 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1271 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001272 // use the OnuVendor identification from this device for the internal unique name
1273 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001274 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001275 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001276 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001277 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001278 "device-id": dh.DeviceID, "error": err})
1279 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001280 }
mpagenko183647c2021-06-08 15:25:04 +00001281 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001282 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001283 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001284 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001285 } //else
1286 dh.lockUpgradeFsm.RUnlock()
1287
1288 // 2.) check if requested image-version equals the inactive one and start its activation
1289 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1290 var inactiveImageID uint16
1291 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1292 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001293 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1294 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001295 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001296 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001297 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001298 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001299 if err == nil {
1300 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1301 inactiveImageID, aCommitRequest); err != nil {
1302 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001303 "device-id": dh.DeviceID, "error": err})
1304 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001305 }
1306 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001307 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001308 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001309 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001310 } //else
1311 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001312 "device-id": dh.DeviceID, "error": err})
1313 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001314}
1315
1316//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001317func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1318 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001319 var err error
1320 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1321 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1322 // 2.) commitment of the active image
1323
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001324 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001325 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001326 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1327 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001328 }
1329 dh.lockUpgradeFsm.RLock()
1330 if dh.pOnuUpradeFsm != nil {
1331 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001332 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001333 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001334 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1335 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001336 }
mpagenko59862f02021-10-11 08:53:18 +00001337 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1338 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1339 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1340 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001341 // use the OnuVendor identification from this device for the internal unique name
1342 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001343 // 1.) check a started upgrade process and relay the commitment request to it
1344 // the running upgrade may be based either on the imageIdentifier (started from download)
1345 // or on the imageVersion (started from pure activation)
1346 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1347 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001348 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001349 "device-id": dh.DeviceID, "error": err})
1350 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001351 }
mpagenko183647c2021-06-08 15:25:04 +00001352 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001353 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001354 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001355 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001356 } //else
1357 dh.lockUpgradeFsm.RUnlock()
1358
mpagenko183647c2021-06-08 15:25:04 +00001359 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001360 var activeImageID uint16
1361 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1362 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001363 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1364 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001365 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001366 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001367 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001368 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001369 if err == nil {
1370 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1371 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001372 "device-id": dh.DeviceID, "error": err})
1373 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001374 }
1375 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001376 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001377 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001378 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001379 } //else
1380 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001381 "device-id": dh.DeviceID, "error": err})
1382 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001383}
1384
mpagenkoaa3afe92021-05-21 16:20:58 +00001385func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001386 aVersion string) *voltha.ImageState {
1387 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001388 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001389 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001390 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001391 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1392 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1393 if aVersion == dh.pLastUpgradeImageState.Version {
1394 pImageState = dh.pLastUpgradeImageState
1395 } else { //state request for an image version different from last processed image version
1396 pImageState = &voltha.ImageState{
1397 Version: aVersion,
1398 //we cannot state something concerning this version
1399 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1400 Reason: voltha.ImageState_NO_ERROR,
1401 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1402 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001403 }
1404 }
mpagenko38662d02021-08-11 09:45:19 +00001405 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001406}
1407
1408func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1409 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001410 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001411 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001412 dh.lockUpgradeFsm.RLock()
1413 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001414 dh.lockUpgradeFsm.RUnlock()
1415 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001416 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001417 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1418 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1419 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1420 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1421 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1422 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001423 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1424 dh.upgradeCanceled = true
1425 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1426 }
mpagenko45586762021-10-01 08:30:22 +00001427 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001428 } else {
mpagenko45586762021-10-01 08:30:22 +00001429 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001430 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1431 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1432 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1433 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1434 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1435 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001436 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1437 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001438 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1439 //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 +00001440 }
1441}
1442
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001443func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1444
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001445 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001446
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001447 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001448 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001449 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1450 pDevEntry.MutexOnuImageStatus.Lock()
1451 pDevEntry.POnuImageStatus = onuImageStatus
1452 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001453
1454 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001455 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001456 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1457 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001458 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1459 pDevEntry.MutexOnuImageStatus.Lock()
1460 pDevEntry.POnuImageStatus = nil
1461 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001462 return images, err
1463}
1464
Himani Chawla6d2ae152020-09-02 13:11:20 +05301465// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001466// #####################################################################################
1467
1468// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301469// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001470
dbainbri4d3a0dc2020-12-02 00:33:42 +00001471func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001472 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 +00001473}
1474
1475// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001476func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001477
dbainbri4d3a0dc2020-12-02 00:33:42 +00001478 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001479 var err error
1480
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001481 // populate what we know. rest comes later after mib sync
1482 dh.device.Root = false
1483 dh.device.Vendor = "OpenONU"
1484 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001485 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
1486 dh.SetDeviceReason(cmn.DrActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001487
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001488 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001489
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001490 if !dh.IsReconciling() {
1491 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001492 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1493 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1494 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301495 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001496 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001497 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001498 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001499 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001500
Himani Chawla4d908332020-08-31 12:30:20 +05301501 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001502 dh.ponPortNumber = dh.device.ParentPortNo
1503
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001504 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1505 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1506 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001507 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001508 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301509 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001510
1511 /*
1512 self._pon = PonPort.create(self, self._pon_port_number)
1513 self._pon.add_peer(self.parent_id, self._pon_port_number)
1514 self.logger.debug('adding-pon-port-to-agent',
1515 type=self._pon.get_port().type,
1516 admin_state=self._pon.get_port().admin_state,
1517 oper_status=self._pon.get_port().oper_status,
1518 )
1519 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001520 if !dh.IsReconciling() {
1521 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001522 var ponPortNo uint32 = 1
1523 if dh.ponPortNumber != 0 {
1524 ponPortNo = dh.ponPortNumber
1525 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001526
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001527 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001528 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001529 PortNo: ponPortNo,
1530 Label: fmt.Sprintf("pon-%d", ponPortNo),
1531 Type: voltha.Port_PON_ONU,
1532 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301533 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001534 PortNo: ponPortNo}}, // Peer port is parent's port number
1535 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001536 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001537 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001538 e.Cancel(err)
1539 return
1540 }
1541 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001542 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001543 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001544 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001545}
1546
1547// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001548func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001549
dbainbri4d3a0dc2020-12-02 00:33:42 +00001550 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001551 var err error
1552 /*
1553 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1554 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1555 return nil
1556 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001557 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1558 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001559 e.Cancel(err)
1560 return
1561 }
1562
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001563 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001564 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001565 // reconcilement will be continued after mib download is done
1566 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001567
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001568 /*
1569 ############################################################################
1570 # Setup Alarm handler
1571 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1572 device.serial_number)
1573 ############################################################################
1574 # Setup PM configuration for this device
1575 # Pass in ONU specific options
1576 kwargs = {
1577 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1578 'heartbeat': self.heartbeat,
1579 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1580 }
1581 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1582 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1583 self.logical_device_id, device.serial_number,
1584 grouped=True, freq_override=False, **kwargs)
1585 pm_config = self._pm_metrics.make_proto()
1586 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1587 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1588 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1589
1590 # Note, ONU ID and UNI intf set in add_uni_port method
1591 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1592 ani_ports=[self._pon])
1593
1594 # Code to Run OMCI Test Action
1595 kwargs_omci_test_action = {
1596 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1597 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1598 }
1599 serial_number = device.serial_number
1600 self._test_request = OmciTestRequest(self.core_proxy,
1601 self.omci_agent, self.device_id,
1602 AniG, serial_number,
1603 self.logical_device_id,
1604 exclusive=False,
1605 **kwargs_omci_test_action)
1606
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001607 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001608 else:
1609 self.logger.info('onu-already-activated')
1610 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001611
dbainbri4d3a0dc2020-12-02 00:33:42 +00001612 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001613}
1614
1615// doStateConnected get the device info and update to voltha core
1616// for comparison of the original method (not that easy to uncomment): compare here:
1617// voltha-openolt-adapter/adaptercore/device_handler.go
1618// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001619func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001620
dbainbri4d3a0dc2020-12-02 00:33:42 +00001621 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301622 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001623 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001624 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001625}
1626
1627// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001628func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001629
dbainbri4d3a0dc2020-12-02 00:33:42 +00001630 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301631 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001632 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001633 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001634
1635 /*
1636 // Synchronous call to update device state - this method is run in its own go routine
1637 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1638 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001639 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 +00001640 return err
1641 }
1642 return nil
1643 */
1644}
1645
1646// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001648
dbainbri4d3a0dc2020-12-02 00:33:42 +00001649 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001650 var err error
1651
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001652 device := dh.device
1653 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001654 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001655 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001656 e.Cancel(err)
1657 return
1658 }
1659
1660 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001661 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001662 /*
1663 // Update the all ports state on that device to disable
1664 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001665 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001666 return er
1667 }
1668
1669 //Update the device oper state and connection status
1670 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1671 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1672 dh.device = cloned
1673
1674 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001675 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001676 return er
1677 }
1678
1679 //get the child device for the parent device
1680 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1681 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001682 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001683 return err
1684 }
1685 for _, onuDevice := range onuDevices.Items {
1686
1687 // Update onu state as down in onu adapter
1688 onuInd := oop.OnuIndication{}
1689 onuInd.OperState = "down"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001690 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001691 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1692 if er != nil {
1693 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001694 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001695 //Do not return here and continue to process other ONUs
1696 }
1697 }
1698 // * Discovered ONUs entries need to be cleared , since after OLT
1699 // is up, it starts sending discovery indications again* /
1700 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001701 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001702 return nil
1703 */
Himani Chawla4d908332020-08-31 12:30:20 +05301704 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001705 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001706 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001707}
1708
Himani Chawla6d2ae152020-09-02 13:11:20 +05301709// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001710// #################################################################################
1711
1712// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301713// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001714
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001715//GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
1716func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001717 dh.lockDevice.RLock()
1718 pOnuDeviceEntry := dh.pOnuOmciDevice
1719 if aWait && pOnuDeviceEntry == nil {
1720 //keep the read sema short to allow for subsequent write
1721 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001722 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001723 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1724 // so it might be needed to wait here for that event with some timeout
1725 select {
1726 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001727 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001728 return nil
1729 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001730 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001731 // if written now, we can return the written value without sema
1732 return dh.pOnuOmciDevice
1733 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001734 }
mpagenko3af1f032020-06-10 08:53:41 +00001735 dh.lockDevice.RUnlock()
1736 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001737}
1738
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001739//setDeviceHandlerEntries sets the ONU device entry within the handler
1740func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1741 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001742 dh.lockDevice.Lock()
1743 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001744 dh.pOnuOmciDevice = apDeviceEntry
1745 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001746 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301747 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001748 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001749}
1750
Himani Chawla6d2ae152020-09-02 13:11:20 +05301751//addOnuDeviceEntry creates a new ONU device or returns the existing
1752func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001753 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001754
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001755 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001756 if deviceEntry == nil {
1757 /* costum_me_map in python code seems always to be None,
1758 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1759 /* also no 'clock' argument - usage open ...*/
1760 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001761 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1762 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1763 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1764 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1765 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001766 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001767 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001768 // fire deviceEntry ready event to spread to possibly waiting processing
1769 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001770 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001771 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001772 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001773 }
1774 // might be updated with some error handling !!!
1775 return nil
1776}
1777
dbainbri4d3a0dc2020-12-02 00:33:42 +00001778func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1779 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001780 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1781
1782 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001783
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001784 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001785 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001786 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1787 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001788 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001789 if !dh.IsReconciling() {
1790 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001791 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001792 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001793 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001794 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001795 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001796
1797 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001798 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001799 OperStatus: voltha.OperStatus_ACTIVATING,
1800 ConnStatus: voltha.ConnectStatus_REACHABLE,
1801 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001802 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001803 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001804 }
1805 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001806 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001807 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001808
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001809 pDevEntry.MutexPersOnuConfig.RLock()
1810 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1811 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001812 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 +00001813 log.Fields{"device-id": dh.DeviceID})
1814 dh.StopReconciling(ctx, true)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001815 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001816 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001817 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001818 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001819 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1820 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1821 // 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 +00001822 // 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 +00001823 // so let's just try to keep it simple ...
1824 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001825 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001826 if err != nil || device == nil {
1827 //TODO: needs to handle error scenarios
1828 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1829 return errors.New("Voltha Device not found")
1830 }
1831 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001832
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001833 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001834 return err
mpagenko3af1f032020-06-10 08:53:41 +00001835 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001836
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001837 _ = dh.deviceReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001838
1839 /* this might be a good time for Omci Verify message? */
1840 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001841 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001842 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001843 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001844 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001845
1846 /* give the handler some time here to wait for the OMCi verification result
1847 after Timeout start and try MibUpload FSM anyway
1848 (to prevent stopping on just not supported OMCI verification from ONU) */
1849 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001850 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001851 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001852 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001853 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001854 }
1855
1856 /* In py code it looks earlier (on activate ..)
1857 # Code to Run OMCI Test Action
1858 kwargs_omci_test_action = {
1859 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1860 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1861 }
1862 serial_number = device.serial_number
1863 self._test_request = OmciTestRequest(self.core_proxy,
1864 self.omci_agent, self.device_id,
1865 AniG, serial_number,
1866 self.logical_device_id,
1867 exclusive=False,
1868 **kwargs_omci_test_action)
1869 ...
1870 # Start test requests after a brief pause
1871 if not self._test_request_started:
1872 self._test_request_started = True
1873 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1874 reactor.callLater(tststart, self._test_request.start_collector)
1875
1876 */
1877 /* which is then: in omci_test_request.py : */
1878 /*
1879 def start_collector(self, callback=None):
1880 """
1881 Start the collection loop for an adapter if the frequency > 0
1882
1883 :param callback: (callable) Function to call to collect PM data
1884 """
1885 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1886 if callback is None:
1887 callback = self.perform_test_omci
1888
1889 if self.lc is None:
1890 self.lc = LoopingCall(callback)
1891
1892 if self.default_freq > 0:
1893 self.lc.start(interval=self.default_freq / 10)
1894
1895 def perform_test_omci(self):
1896 """
1897 Perform the initial test request
1898 """
1899 ani_g_entities = self._device.configuration.ani_g_entities
1900 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1901 is not None else None
1902 self._entity_id = ani_g_entities_ids[0]
1903 self.logger.info('perform-test', entity_class=self._entity_class,
1904 entity_id=self._entity_id)
1905 try:
1906 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1907 result = yield self._device.omci_cc.send(frame)
1908 if not result.fields['omci_message'].fields['success_code']:
1909 self.logger.info('Self-Test Submitted Successfully',
1910 code=result.fields[
1911 'omci_message'].fields['success_code'])
1912 else:
1913 raise TestFailure('Test Failure: {}'.format(
1914 result.fields['omci_message'].fields['success_code']))
1915 except TimeoutError as e:
1916 self.deferred.errback(failure.Failure(e))
1917
1918 except Exception as e:
1919 self.logger.exception('perform-test-Error', e=e,
1920 class_id=self._entity_class,
1921 entity_id=self._entity_id)
1922 self.deferred.errback(failure.Failure(e))
1923
1924 */
1925
1926 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001927 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001928
mpagenko1cc3cb42020-07-27 15:24:38 +00001929 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1930 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1931 * 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 +05301932 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001933 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001934 //call MibUploadFSM - transition up to state UlStInSync
1935 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001936 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001937 if pMibUlFsm.Is(mib.UlStDisabled) {
1938 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
1939 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
1940 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301941 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001942 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301943 //Determine ONU status and start/re-start MIB Synchronization tasks
1944 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001945 if pDevEntry.IsNewOnu() {
1946 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
1947 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
1948 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001949 }
Himani Chawla4d908332020-08-31 12:30:20 +05301950 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001951 if err := pMibUlFsm.Event(mib.UlEvExamineMds); err != nil {
1952 logger.Errorw(ctx, "MibSyncFsm: Can't go to state examine_mds", log.Fields{"device-id": dh.DeviceID, "err": err})
1953 return fmt.Errorf("can't go to examine_mds: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301954 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001955 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001956 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001957 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001958 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001959 "device-id": dh.DeviceID})
1960 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001961 }
1962 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001963 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
1964 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001965 }
1966 return nil
1967}
1968
dbainbri4d3a0dc2020-12-02 00:33:42 +00001969func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001970 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001971 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001972 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
1973 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001974
mpagenko900ee4b2020-10-12 11:56:34 +00001975 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1976 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1977 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001978 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001979 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001980 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001981 // abort: system behavior is just unstable ...
1982 return err
1983 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001984 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001985 _ = 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 +00001986
1987 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1988 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1989 //stop the device entry which resets the attached omciCC
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001990 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001991 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001992 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
1993 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001994 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001995 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001996
1997 //TODO!!! remove existing traffic profiles
1998 /* from py code, if TP's exist, remove them - not yet implemented
1999 self._tp = dict()
2000 # Let TP download happen again
2001 for uni_id in self._tp_service_specific_task:
2002 self._tp_service_specific_task[uni_id].clear()
2003 for uni_id in self._tech_profile_download_done:
2004 self._tech_profile_download_done[uni_id].clear()
2005 */
2006
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002007 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002008
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002009 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002010
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002011 if err := dh.deviceReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002012 // abort: system behavior is just unstable ...
2013 return err
2014 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002015 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002016 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002017 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002018 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002019 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2020 OperStatus: voltha.OperStatus_DISCOVERED,
2021 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002022 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002023 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002024 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002025 // abort: system behavior is just unstable ...
2026 return err
2027 }
2028 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002029 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002030 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002031 return nil
2032}
2033
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002034func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002035 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2036 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2037 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2038 // and using the stop/reset event should never harm
2039
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002040 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002041 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002042 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2043 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00002044 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002045 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002046 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002047 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002048 pDevEntry.MutexOnuImageStatus.RLock()
2049 if pDevEntry.POnuImageStatus != nil {
2050 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002051 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002052 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002053
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002054 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002055 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002056 }
2057 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002058 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002059 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002060 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002061 }
2062 //port lock/unlock FSM's may be active
2063 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002064 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002065 }
2066 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002067 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002068 }
2069 //techProfile related PonAniConfigFsm FSM may be active
2070 if dh.pOnuTP != nil {
2071 // should always be the case here
2072 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002073 if dh.pOnuTP.PAniConfigFsm != nil {
2074 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2075 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002076 }
mpagenko900ee4b2020-10-12 11:56:34 +00002077 }
2078 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002079 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002080 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002081 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002082 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002083 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002084 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002085 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002086 } else {
2087 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002088 }
2089 }
2090 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002091 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002092 // Stop collector routine
2093 dh.stopCollector <- true
2094 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002095 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302096 dh.stopAlarmManager <- true
2097 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002098 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002099 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002100 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302101
Girish Gowdrae95687a2021-09-08 16:30:58 -07002102 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2103
mpagenko80622a52021-02-09 16:53:23 +00002104 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002105 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002106 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002107 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002108 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002109 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002110 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002111 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2112 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2113 // (even though it may also run into direct cancellation, a bit hard to verify here)
2114 // so don't set 'dh.upgradeCanceled = true' here!
2115 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2116 }
mpagenko38662d02021-08-11 09:45:19 +00002117 }
mpagenko80622a52021-02-09 16:53:23 +00002118
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002119 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002120 return nil
2121}
2122
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002123func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2124 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 +05302125
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002126 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002127 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002128 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002129 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002130 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002131 _ = dh.deviceReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling())
2132 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002133
mpagenkoa40e99a2020-11-17 13:50:39 +00002134 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2135 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2136 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2137 * disable/enable toggling here to allow traffic
2138 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2139 * like the py comment says:
2140 * # start by locking all the unis till mib sync and initial mib is downloaded
2141 * # this way we can capture the port down/up events when we are ready
2142 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302143
mpagenkoa40e99a2020-11-17 13:50:39 +00002144 // Init Uni Ports to Admin locked state
2145 // *** should generate UniLockStateDone event *****
2146 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002147 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002148 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002149 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002150 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002151 }
2152}
2153
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002154func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2155 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302156 /* Mib download procedure -
2157 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2158 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002159 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002160 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002161 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002162 return
2163 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002164 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302165 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002166 if pMibDlFsm.Is(mib.DlStDisabled) {
2167 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2168 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 +05302169 // maybe try a FSM reset and then again ... - TODO!!!
2170 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002171 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302172 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002173 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2174 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302175 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002176 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302177 //Begin MIB data download (running autonomously)
2178 }
2179 }
2180 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002181 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002182 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302183 // maybe try a FSM reset and then again ... - TODO!!!
2184 }
2185 /***** Mib download started */
2186 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002187 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302188 }
2189}
2190
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002191func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2192 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302193 //initiate DevStateUpdate
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002194 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002195 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002196 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002197 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2198 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2199 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2200 dh.checkOnOnuImageCommit(ctx)
khenaidoo7d3c5582021-08-11 18:09:44 -04002201 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002202 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002203 ConnStatus: voltha.ConnectStatus_REACHABLE,
2204 OperStatus: voltha.OperStatus_ACTIVE,
2205 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302206 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002207 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302208 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002209 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302210 }
2211 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002212 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002213 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302214 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002215 _ = dh.deviceReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002216
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002217 if !dh.GetCollectorIsRunning() {
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002218 // Start PM collector routine
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002219 go dh.StartCollector(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002220 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002221 if !dh.GetAlarmManagerIsRunning(ctx) {
2222 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002223 }
2224
Girish Gowdrae95687a2021-09-08 16:30:58 -07002225 // Start flow handler routines per UNI
2226 for _, uniPort := range dh.uniEntityMap {
2227 // only if this port was enabled for use by the operator at startup
2228 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2229 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2230 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2231 }
2232 }
2233 }
2234
Girish Gowdrae0140f02021-02-02 16:55:09 -08002235 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002236 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002237 // There is no way we should be landing here, but if we do then
2238 // there is nothing much we can do about this other than log error
2239 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2240 }
2241
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002242 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002243
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002244 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002245 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002246 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002247 return
2248 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002249 pDevEntry.MutexPersOnuConfig.RLock()
2250 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2251 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002252 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002253 log.Fields{"device-id": dh.DeviceID})
2254 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002255 // reconcilement will be continued after ani config is done
2256 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002257 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002258 // *** should generate UniUnlockStateDone event *****
2259 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002260 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002261 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002262 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002263 dh.runUniLockFsm(ctx, false)
2264 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302265 }
2266}
2267
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002268func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2269 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302270
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002271 if !dh.IsReconciling() {
2272 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002273 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002274 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2275 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002276 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002277 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002278 return
2279 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002280 pDevEntry.MutexPersOnuConfig.Lock()
2281 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2282 pDevEntry.MutexPersOnuConfig.Unlock()
2283 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002284 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002285 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002286 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302287 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002288 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 +00002289 log.Fields{"device-id": dh.DeviceID})
2290 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002291 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302292 }
2293}
2294
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002295func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002296 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002297 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002298
2299 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002300 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002301 ConnStatus: voltha.ConnectStatus_REACHABLE,
2302 OperStatus: voltha.OperStatus_UNKNOWN,
2303 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002304 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002305 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002306 }
2307
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002308 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002309 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002310 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002311
2312 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002313 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002314
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002315 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002316 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002317 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002318 return
2319 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002320 pDevEntry.MutexPersOnuConfig.Lock()
2321 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2322 pDevEntry.MutexPersOnuConfig.Unlock()
2323 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002324 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002325 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002326 }
mpagenko900ee4b2020-10-12 11:56:34 +00002327}
2328
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002329func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002330 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002331 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002332 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002333 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002334 ConnStatus: voltha.ConnectStatus_REACHABLE,
2335 OperStatus: voltha.OperStatus_ACTIVE,
2336 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002337 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002338 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002339 }
2340
dbainbri4d3a0dc2020-12-02 00:33:42 +00002341 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002342 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002343 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002344 _ = dh.deviceReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002345
2346 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002347 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002348
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002349 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002350 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002351 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002352 return
2353 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002354 pDevEntry.MutexPersOnuConfig.Lock()
2355 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2356 pDevEntry.MutexPersOnuConfig.Unlock()
2357 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002358 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002359 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002360 }
mpagenko900ee4b2020-10-12 11:56:34 +00002361}
2362
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002363func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2364 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2365 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
2366 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
2367 DeviceId: dh.DeviceID,
2368 OperStatus: voltha.OperStatus_FAILED,
2369 }); err != nil {
2370 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2371 }
2372}
2373
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002374func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2375 if devEvent == cmn.OmciAniConfigDone {
2376 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002377 // attention: the device reason update is done based on ONU-UNI-Port related activity
2378 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002379 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002380 // 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 +00002381 _ = dh.deviceReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302382 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002383 if dh.IsReconciling() {
2384 go dh.ReconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002385 }
2386 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002387 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002388 // attention: the device reason update is done based on ONU-UNI-Port related activity
2389 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002390 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002391 // 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 +00002392 _ = dh.deviceReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002393 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002394 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302395}
2396
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002397func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002398 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002399 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302400 // attention: the device reason update is done based on ONU-UNI-Port related activity
2401 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302402
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002403 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2404 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002405 // which may be the case from some previous actvity on another UNI Port of the ONU
2406 // or even some previous flow add activity on the same port
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002407 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling())
2408 if dh.IsReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002409 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002410 }
2411 }
2412 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002413 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002414 //not relevant for reconcile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002415 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002416 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302417 }
mpagenkof1fc3862021-02-16 10:09:52 +00002418
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002419 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002420 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002421 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002422 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002423 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002424 }
2425 } else {
2426 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002427 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002428 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302429}
2430
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002431//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
2432func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302433 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002434 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002435 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002436 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002437 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002438 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002439 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002440 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002441 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002442 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002443 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002444 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002445 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002446 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002447 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002448 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002449 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002450 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002451 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002452 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002453 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002454 case cmn.UniEnableStateFailed:
2455 {
2456 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2457 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002458 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002459 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002460 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002461 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002462 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002463 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002464 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002465 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002466 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002467 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002468 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002469 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002470 default:
2471 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002472 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002473 }
2474 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002475}
2476
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002477func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002478 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002479 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302480 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002481 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002482 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002483 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302484 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002485 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002486 if pUniPort == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002487 logger.Warnw(ctx, "OnuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002488 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002489 //store UniPort with the System-PortNumber key
2490 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002491 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002492 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002493 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
2494 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002495 } //error logging already within UniPort method
2496 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002497 logger.Debugw(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002498 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002499 }
2500 }
2501}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002502
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002503func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2504 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002505 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002506 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002507 return
2508 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002509 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002510 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002511 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2512 for _, mgmtEntityID := range pptpInstKeys {
2513 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002514 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002515 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2516 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002517 }
2518 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002519 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002520 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002521 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002522 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2523 for _, mgmtEntityID := range veipInstKeys {
2524 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002525 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002526 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2527 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002528 }
2529 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002530 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002531 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002532 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002533 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2534 for _, mgmtEntityID := range potsInstKeys {
2535 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002536 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002537 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2538 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002539 }
2540 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002541 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002542 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002543 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002544 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002545 return
2546 }
2547
2548 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2549 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2550 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
2551 for i := 0; i < int(uniCnt); i++ {
2552 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
2553 dh.stopFlowMonitoringRoutine[i] = make(chan bool)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002554 }
2555}
2556
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002557// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2558func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002559 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302560 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002561 // with following remark:
2562 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2563 // # load on the core
2564
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002565 // 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 +00002566
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002567 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002568 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002569 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2570 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2571 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2572 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002573 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002574 go func(port *cmn.OnuUniPort) {
khenaidoo7d3c5582021-08-11 18:09:44 -04002575 if err := dh.updatePortStateInCore(ctx, &ic.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002576 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002577 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002578 PortNo: port.PortNo,
2579 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002580 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002581 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 -04002582 }
2583 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002584 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002585 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002586 }
mpagenko3af1f032020-06-10 08:53:41 +00002587 }
2588 }
2589}
2590
2591// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002592func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2593 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002594 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2595 for uniNo, uniPort := range dh.uniEntityMap {
2596 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002597
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002598 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2599 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2600 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2601 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002602 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002603 go func(port *cmn.OnuUniPort) {
khenaidoo7d3c5582021-08-11 18:09:44 -04002604 if err := dh.updatePortStateInCore(ctx, &ic.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002605 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002606 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002607 PortNo: port.PortNo,
2608 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002609 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002610 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 -04002611 }
2612 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002613 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002614 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002615 }
2616
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002617 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002618 }
2619}
2620
2621// ONU_Active/Inactive announcement on system KAFKA bus
2622// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002623func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002624 var de voltha.DeviceEvent
2625 eventContext := make(map[string]string)
2626 //Populating event context
2627 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002628 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002629 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002630 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302631 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002632 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 +00002633 }
2634 oltSerialNumber := parentDevice.SerialNumber
2635
2636 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2637 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2638 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302639 eventContext["olt-serial-number"] = oltSerialNumber
2640 eventContext["device-id"] = aDeviceID
2641 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002642 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002643 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2644 deviceEntry.MutexPersOnuConfig.RLock()
2645 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2646 deviceEntry.MutexPersOnuConfig.RUnlock()
2647 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
2648 deviceEntry.MutexPersOnuConfig.RLock()
2649 eventContext["vendor"] = deviceEntry.SOnuPersistentData.PersVendorID
2650 deviceEntry.MutexPersOnuConfig.RUnlock()
2651 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002652 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2653 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2654 } else {
2655 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2656 log.Fields{"device-id": aDeviceID})
2657 return
2658 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002659
2660 /* Populating device event body */
2661 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302662 de.ResourceId = aDeviceID
2663 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002664 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2665 de.Description = fmt.Sprintf("%s Event - %s - %s",
2666 cEventObjectType, cOnuActivatedEvent, "Raised")
2667 } else {
2668 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2669 de.Description = fmt.Sprintf("%s Event - %s - %s",
2670 cEventObjectType, cOnuActivatedEvent, "Cleared")
2671 }
2672 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002673 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2674 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302675 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002676 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002677 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302678 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002679}
2680
Himani Chawla4d908332020-08-31 12:30:20 +05302681// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002682func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2683 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002684 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302685 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002686 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002687 sFsmName = "LockStateFSM"
2688 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002689 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002690 sFsmName = "UnLockStateFSM"
2691 }
mpagenko3af1f032020-06-10 08:53:41 +00002692
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002693 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002694 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002695 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002696 return
2697 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002698 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002699 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302700 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002701 dh.pLockStateFsm = pLSFsm
2702 } else {
2703 dh.pUnlockStateFsm = pLSFsm
2704 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002705 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002706 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002707 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002708 }
2709}
2710
2711// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002712func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002713 /* Uni Port lock/unlock procedure -
2714 ***** should run via 'adminDone' state and generate the argument requested event *****
2715 */
2716 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302717 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002718 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002719 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2720 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002721 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2722 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002723 }
2724 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002725 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002726 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2727 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002728 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2729 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002730 }
2731 }
2732 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002733 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2734 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002735 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002736 // maybe try a FSM reset and then again ... - TODO!!!
2737 } else {
2738 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002739 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002740 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002741 }
2742 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002743 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002744 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002745 // maybe try a FSM reset and then again ... - TODO!!!
2746 }
2747 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002748 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002749 // maybe try a FSM reset and then again ... - TODO!!!
2750 }
2751}
2752
mpagenko80622a52021-02-09 16:53:23 +00002753// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00002754// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002755func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002756 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002757 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002758 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002759 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002760 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002761 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002762 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002763 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002764 sFsmName, chUpgradeFsm)
2765 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002766 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00002767 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002768 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
2769 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
mpagenko80622a52021-02-09 16:53:23 +00002770 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2771 // maybe try a FSM reset and then again ... - TODO!!!
2772 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2773 }
mpagenko59862f02021-10-11 08:53:18 +00002774 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00002775 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2776 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00002777 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2778 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002779 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002780 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002781 } else {
2782 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002783 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002784 // maybe try a FSM reset and then again ... - TODO!!!
2785 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2786 }
2787 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002788 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002789 // maybe try a FSM reset and then again ... - TODO!!!
2790 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2791 }
2792 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002793 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002794 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2795 }
2796 return nil
2797}
2798
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002799// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
2800func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002801 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002802 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002803 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00002804 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2805 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00002806 dh.pLastUpgradeImageState = apImageState
2807 dh.lockUpgradeFsm.Unlock()
2808 //signal upgradeFsm removed using non-blocking channel send
2809 select {
2810 case dh.upgradeFsmChan <- struct{}{}:
2811 default:
2812 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002813 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00002814 }
mpagenko80622a52021-02-09 16:53:23 +00002815}
2816
mpagenko15ff4a52021-03-02 10:09:20 +00002817// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2818func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002819 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00002820 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002821 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002822 return
2823 }
2824
2825 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00002826 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00002827 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002828 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
2829 dh.lockUpgradeFsm.RUnlock()
2830 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
2831 return
2832 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002833 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00002834 if pUpgradeStatemachine != nil {
2835 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2836 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002837 UpgradeState := pUpgradeStatemachine.Current()
2838 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
2839 (UpgradeState == swupg.UpgradeStRequestingActivate) {
2840 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00002841 // 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 +00002842 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00002843 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
2844 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00002845 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00002846 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002847 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00002848 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2849 dh.upgradeCanceled = true
2850 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2851 }
mpagenko15ff4a52021-03-02 10:09:20 +00002852 return
2853 }
mpagenko59862f02021-10-11 08:53:18 +00002854 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002855 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
2856 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00002857 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002858 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
mpagenko1f8e8822021-06-25 14:10:21 +00002859 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
2860 return
2861 }
2862 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002863 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00002864 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002865 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
2866 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
mpagenko1f8e8822021-06-25 14:10:21 +00002867 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2868 return
2869 }
2870 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002871 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00002872 }
2873 } else {
2874 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 +00002875 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00002876 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2877 dh.upgradeCanceled = true
2878 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2879 }
mpagenko1f8e8822021-06-25 14:10:21 +00002880 }
mpagenko15ff4a52021-03-02 10:09:20 +00002881 return
2882 }
mpagenko59862f02021-10-11 08:53:18 +00002883 dh.lockUpgradeFsm.RUnlock()
2884 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2885 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00002886 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2887 dh.upgradeCanceled = true
2888 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2889 }
mpagenko59862f02021-10-11 08:53:18 +00002890 return
2891 }
2892 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2893 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2894 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2895 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
2896 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2897 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
2898 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00002899 }
mpagenko15ff4a52021-03-02 10:09:20 +00002900 }
2901 }
2902 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002903 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002904 }
mpagenko59862f02021-10-11 08:53:18 +00002905 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00002906}
2907
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002908//SetBackend provides a DB backend for the specified path on the existing KV client
2909func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002910
2911 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002912 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07002913 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00002914 kvbackend := &db.Backend{
2915 Client: dh.pOpenOnuAc.kvClient,
2916 StoreType: dh.pOpenOnuAc.KVStoreType,
2917 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002918 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002919 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2920 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002921
mpagenkoaf801632020-07-03 10:00:42 +00002922 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002923}
khenaidoo7d3c5582021-08-11 18:09:44 -04002924func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302925 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002926
mpagenkodff5dda2020-08-28 11:52:01 +00002927 for _, field := range flow.GetOfbFields(apFlowItem) {
2928 switch field.Type {
2929 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2930 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002931 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002932 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2933 }
mpagenko01e726e2020-10-23 09:45:29 +00002934 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002935 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2936 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302937 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002938 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302939 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2940 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002941 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2942 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002943 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002944 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302945 return
mpagenkodff5dda2020-08-28 11:52:01 +00002946 }
2947 }
mpagenko01e726e2020-10-23 09:45:29 +00002948 */
mpagenkodff5dda2020-08-28 11:52:01 +00002949 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2950 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302951 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002952 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302953 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002954 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302955 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002956 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002957 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302958 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002959 }
2960 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2961 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302962 *loAddPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002963 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002964 "PCP": loAddPcp})
2965 }
2966 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2967 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002968 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002969 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2970 }
2971 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2972 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002973 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002974 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2975 }
2976 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2977 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002978 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002979 "IPv4-DST": field.GetIpv4Dst()})
2980 }
2981 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2982 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002983 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002984 "IPv4-SRC": field.GetIpv4Src()})
2985 }
2986 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2987 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002988 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002989 "Metadata": field.GetTableMetadata()})
2990 }
2991 /*
2992 default:
2993 {
2994 //all other entires ignored
2995 }
2996 */
2997 }
2998 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302999}
mpagenkodff5dda2020-08-28 11:52:01 +00003000
khenaidoo7d3c5582021-08-11 18:09:44 -04003001func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003002 for _, action := range flow.GetActions(apFlowItem) {
3003 switch action.Type {
3004 /* not used:
3005 case of.OfpActionType_OFPAT_OUTPUT:
3006 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003007 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003008 "Output": action.GetOutput()})
3009 }
3010 */
3011 case of.OfpActionType_OFPAT_PUSH_VLAN:
3012 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003013 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003014 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3015 }
3016 case of.OfpActionType_OFPAT_SET_FIELD:
3017 {
3018 pActionSetField := action.GetSetField()
3019 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003020 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003021 "OxcmClass": pActionSetField.Field.OxmClass})
3022 }
3023 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303024 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003025 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303026 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003027 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303028 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003029 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303030 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003031 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003032 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003033 "Type": pActionSetField.Field.GetOfbField().Type})
3034 }
3035 }
3036 /*
3037 default:
3038 {
3039 //all other entires ignored
3040 }
3041 */
3042 }
3043 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303044}
3045
3046//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003047func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003048 apFlowMetaData *voltha.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303049 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3050 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
3051 var loAddPcp, loSetPcp uint8
3052 var loIPProto uint32
3053 /* the TechProfileId is part of the flow Metadata - compare also comment within
3054 * OLT-Adapter:openolt_flowmgr.go
3055 * Metadata 8 bytes:
3056 * Most Significant 2 Bytes = Inner VLAN
3057 * Next 2 Bytes = Tech Profile ID(TPID)
3058 * Least Significant 4 Bytes = Port ID
3059 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3060 * subscriber related flows.
3061 */
3062
dbainbri4d3a0dc2020-12-02 00:33:42 +00003063 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303064 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003065 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003066 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003067 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303068 }
mpagenko551a4d42020-12-08 18:09:20 +00003069 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003070 loCookie := apFlowItem.GetCookie()
3071 loCookieSlice := []uint64{loCookie}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003072 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003073 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05303074
dbainbri4d3a0dc2020-12-02 00:33:42 +00003075 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003076 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303077 if loIPProto == 2 {
3078 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3079 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003080 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003081 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303082 return nil
3083 }
mpagenko01e726e2020-10-23 09:45:29 +00003084 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003085 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003086
3087 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003088 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003089 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003090 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3091 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3092 //TODO!!: Use DeviceId within the error response to rwCore
3093 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003094 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003095 }
3096 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003097 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003098 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3099 } else {
3100 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3101 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3102 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303103 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003104 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003105 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003106 }
mpagenko9a304ea2020-12-16 15:54:01 +00003107
ozgecanetsia82b91a62021-05-21 18:54:49 +03003108 var meter *voltha.OfpMeterConfig
3109 if apFlowMetaData != nil {
3110 meter = apFlowMetaData.Meters[0]
3111 }
mpagenkobc4170a2021-08-17 16:42:10 +00003112 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3113 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3114 // when different rules are requested concurrently for the same uni
3115 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3116 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3117 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003118 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3119 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003120 //SetUniFlowParams() may block on some rule that is suspended-to-add
3121 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003122 // Also the error is returned to caller via response channel
3123 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
3124 loMatchVlan, loSetVlan, loSetPcp, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003125 dh.lockVlanConfig.RUnlock()
3126 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003127 return
mpagenkodff5dda2020-08-28 11:52:01 +00003128 }
mpagenkobc4170a2021-08-17 16:42:10 +00003129 dh.lockVlanConfig.RUnlock()
3130 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003131 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003132 loMatchVlan, loSetVlan, loSetPcp, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003133 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003134 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003135 if err != nil {
3136 *respChan <- err
3137 }
mpagenko01e726e2020-10-23 09:45:29 +00003138}
3139
3140//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003141func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003142 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3143 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3144 //no extra check is done on the rule parameters
3145 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3146 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3147 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3148 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003149 // - 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 +00003150 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003151 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003152
3153 /* TT related temporary workaround - should not be needed anymore
3154 for _, field := range flow.GetOfbFields(apFlowItem) {
3155 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3156 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003157 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003158 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3159 if loIPProto == 2 {
3160 // 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 +00003161 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003162 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003163 return nil
3164 }
3165 }
3166 } //for all OfbFields
3167 */
3168
mpagenko9a304ea2020-12-16 15:54:01 +00003169 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003170 dh.lockVlanConfig.RLock()
3171 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003172 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3173 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003174 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3175 return
mpagenko01e726e2020-10-23 09:45:29 +00003176 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003177 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003178 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003179 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003180 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003181 // Push response on the response channel
3182 if respChan != nil {
3183 // 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
3184 select {
3185 case *respChan <- nil:
3186 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3187 default:
3188 }
3189 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003190 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003191}
3192
Himani Chawla26e555c2020-08-31 12:30:20 +05303193// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003194// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003195// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003196func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003197 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 +00003198 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003199
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003200 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003201 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003202 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3203 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003204 }
3205
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003206 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3207 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003208 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003209 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003210 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3211 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003212 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3213 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003214 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003215 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3216 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003217 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003218 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003219 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303220 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003221 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003222 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3223 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003224 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003225 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003226 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3227 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003228 }
3229 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003230 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003231 "device-id": dh.DeviceID})
3232 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003233 }
3234 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003235 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003236 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3237 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003238 }
3239 return nil
3240}
3241
mpagenkofc4f56e2020-11-04 17:17:49 +00003242//VerifyVlanConfigRequest checks on existence of a given uniPort
3243// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003244func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003245 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003246 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003247 for _, uniPort := range dh.uniEntityMap {
3248 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003249 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003250 pCurrentUniPort = uniPort
3251 break //found - end search loop
3252 }
3253 }
3254 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003255 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003256 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003257 return
3258 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003259 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003260}
3261
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003262//VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
3263func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003264 //TODO!! verify and start pending flow configuration
3265 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3266 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003267
3268 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003269 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003270 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003271 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003272 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003273 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003274 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003275 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003276 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3277 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003278 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003279 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003280 } else {
3281 /***** UniVlanConfigFsm continued */
3282 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003283 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3284 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003285 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003286 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3287 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003288 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003289 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003290 } else {
3291 /***** UniVlanConfigFsm continued */
3292 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003293 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3294 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003295 }
mpagenkodff5dda2020-08-28 11:52:01 +00003296 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003297 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003298 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3299 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003300 }
3301 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003302 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 +00003303 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3304 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003305 }
3306 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003307 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003308 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003309 }
mpagenkof1fc3862021-02-16 10:09:52 +00003310 } else {
3311 dh.lockVlanConfig.RUnlock()
3312 }
mpagenkodff5dda2020-08-28 11:52:01 +00003313}
3314
3315//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3316// 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 +00003317func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003318 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003319 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003320 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003321 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003322 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003323 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003324}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003325
mpagenkof1fc3862021-02-16 10:09:52 +00003326//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003327func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003328 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3329 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3330 // obviously then parallel processing on the cancel must be avoided
3331 // deadline context to ensure completion of background routines waited for
3332 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3333 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3334 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3335
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003336 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003337 var wg sync.WaitGroup
3338 wg.Add(1) // for the 1 go routine to finish
3339
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003340 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003341 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3342
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003343 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003344}
3345
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003346//StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003347//available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003348func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3349 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003350
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003351 if dh.IsReconciling() {
3352 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003353 return nil
3354 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003355 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003356
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003357 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003358 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003359 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3360 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003361 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003362 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003363
mpagenkof1fc3862021-02-16 10:09:52 +00003364 if aWriteToKvStore {
3365 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3366 }
3367 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003368}
3369
dbainbri4d3a0dc2020-12-02 00:33:42 +00003370func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003371 defer cancel() //ensure termination of context (may be pro forma)
3372 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003373 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003374 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003375}
3376
dbainbri4d3a0dc2020-12-02 00:33:42 +00003377func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003378
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003379 dh.SetDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003380 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003381 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo7d3c5582021-08-11 18:09:44 -04003382 if err := dh.updateDeviceReasonInCore(ctx, &ic.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003383 DeviceId: dh.DeviceID,
3384 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003385 }); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003386 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003387 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003388 return err
3389 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003390 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", cmn.DeviceReasonMap[deviceReason], dh.DeviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003391 return nil
3392 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003393 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 +00003394 return nil
3395}
3396
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003397func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3398 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003399 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003400 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3401 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003402 }
mpagenkof1fc3862021-02-16 10:09:52 +00003403 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003404}
3405
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003406// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003407// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003408func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3409 dh.lockDevice.RLock()
3410 defer dh.lockDevice.RUnlock()
3411 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003412 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003413 }
3414 return 0, errors.New("error-fetching-uni-port")
3415}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003416
3417// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003418func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3419 var errorsList []error
3420 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 -08003421
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003422 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3423 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3424 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3425
3426 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3427 // successfully.
3428 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3429 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3430 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003431 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 -08003432 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003433 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003434 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003435 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003436}
3437
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003438func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3439 var err error
3440 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003441 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003442
3443 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003444 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003445 errorsList = append(errorsList, err)
3446 }
3447 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003448 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003449
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003450 return errorsList
3451}
3452
3453func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3454 var err error
3455 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003456 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003457 // Check if group metric related config is updated
3458 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003459 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3460 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3461 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003462
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003463 if ok && m.Frequency != v.GroupFreq {
3464 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003465 errorsList = append(errorsList, err)
3466 }
3467 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003468 if ok && m.Enabled != v.Enabled {
3469 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003470 errorsList = append(errorsList, err)
3471 }
3472 }
3473 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003474 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003475 return errorsList
3476}
3477
3478func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3479 var err error
3480 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003481 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003482 // Check if standalone metric related config is updated
3483 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003484 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3485 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3486 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003487
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003488 if ok && m.Frequency != v.SampleFreq {
3489 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003490 errorsList = append(errorsList, err)
3491 }
3492 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003493 if ok && m.Enabled != v.Enabled {
3494 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003495 errorsList = append(errorsList, err)
3496 }
3497 }
3498 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003499 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003500 return errorsList
3501}
3502
3503// nolint: gocyclo
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003504func (dh *deviceHandler) StartCollector(ctx context.Context) {
Girish Gowdrae09a6202021-01-12 18:10:59 -08003505 logger.Debugf(ctx, "startingCollector")
3506
3507 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003508 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303509 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003510 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003511 // Initialize the next metric collection time.
3512 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3513 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003514 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003515 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003516 for {
3517 select {
3518 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003519 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003520 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003521 // Stop the L2 PM FSM
3522 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003523 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3524 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3525 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003526 }
3527 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003528 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003529 }
3530 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003531 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3532 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003533 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003534 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3535 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003536 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003537
Girish Gowdrae09a6202021-01-12 18:10:59 -08003538 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003539 case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3540 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3541 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3542 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3543 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003544 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003545 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003546 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003547 } else {
3548 if dh.pmConfigs.Grouped { // metrics are managed as a group
3549 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003550 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003551
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003552 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3553 // 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 -08003554 // 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 +00003555 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3556 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003557 }
3558 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003559 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3560 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3561 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3562 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003563 }
3564 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003565 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003566
3567 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003568 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3569 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3570 // 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 -08003571 // 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 +00003572 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3573 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003574 }
3575 }
3576 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003577 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3578 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3579 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3580 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003581 }
3582 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003583 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003584 } /* else { // metrics are not managed as a group
3585 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3586 } */
3587 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003588 }
3589 }
3590}
kesavandfdf77632021-01-26 23:40:33 -05003591
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003592func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003593
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003594 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3595 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003596}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003597
Himani Chawla43f95ff2021-06-03 00:24:12 +05303598func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3599 if dh.pOnuMetricsMgr == nil {
3600 return &extension.SingleGetValueResponse{
3601 Response: &extension.GetValueResponse{
3602 Status: extension.GetValueResponse_ERROR,
3603 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3604 },
3605 }
3606 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303607 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303608 return resp
3609}
3610
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003611func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3612 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003613 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003614 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003615 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003616}
3617
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003618func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003619 var pAdapterFsm *cmn.AdapterFsm
3620 //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 +00003621 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003622 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003623 {
mpagenkofbf577d2021-10-12 11:44:33 +00003624 if dh.pOnuOmciDevice != nil {
3625 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3626 } else {
3627 return true //FSM not active - so there is no activity on omci
3628 }
mpagenkof1fc3862021-02-16 10:09:52 +00003629 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003630 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003631 {
mpagenkofbf577d2021-10-12 11:44:33 +00003632 if dh.pOnuOmciDevice != nil {
3633 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3634 } else {
3635 return true //FSM not active - so there is no activity on omci
3636 }
mpagenkof1fc3862021-02-16 10:09:52 +00003637 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003638 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003639 {
mpagenkofbf577d2021-10-12 11:44:33 +00003640 if dh.pLockStateFsm != nil {
3641 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3642 } else {
3643 return true //FSM not active - so there is no activity on omci
3644 }
mpagenkof1fc3862021-02-16 10:09:52 +00003645 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003646 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003647 {
mpagenkofbf577d2021-10-12 11:44:33 +00003648 if dh.pUnlockStateFsm != nil {
3649 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3650 } else {
3651 return true //FSM not active - so there is no activity on omci
3652 }
mpagenkof1fc3862021-02-16 10:09:52 +00003653 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003654 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003655 {
mpagenkofbf577d2021-10-12 11:44:33 +00003656 if dh.pOnuMetricsMgr != nil {
3657 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003658 } else {
3659 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003660 }
3661 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003662 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003663 {
3664 dh.lockUpgradeFsm.RLock()
3665 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003666 if dh.pOnuUpradeFsm != nil {
3667 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3668 } else {
3669 return true //FSM not active - so there is no activity on omci
3670 }
mpagenko80622a52021-02-09 16:53:23 +00003671 }
mpagenkof1fc3862021-02-16 10:09:52 +00003672 default:
3673 {
3674 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003675 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003676 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003677 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003678 }
mpagenkofbf577d2021-10-12 11:44:33 +00003679 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3680 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3681 }
3682 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003683}
3684
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003685func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3686 for _, v := range dh.pOnuTP.PAniConfigFsm {
3687 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003688 return false
3689 }
3690 }
3691 return true
3692}
3693
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003694func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003695 dh.lockVlanConfig.RLock()
3696 defer dh.lockVlanConfig.RUnlock()
3697 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003698 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003699 return false
3700 }
3701 }
3702 return true //FSM not active - so there is no activity on omci
3703}
3704
3705func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3706 dh.lockVlanConfig.RLock()
3707 defer dh.lockVlanConfig.RUnlock()
3708 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003709 if v.PAdaptFsm.PFsm != nil {
3710 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003711 return true //there is at least one VLAN FSM with some active configuration
3712 }
3713 }
3714 }
3715 return false //there is no VLAN FSM with some active configuration
3716}
3717
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003718func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003719 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3720 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3721 return false
3722 }
3723 }
3724 // a further check is done to identify, if at least some data traffic related configuration exists
3725 // 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])
3726 return dh.checkUserServiceExists(ctx)
3727}
3728
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003729func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003730 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3731 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003732 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003733 // TODO: fatal error reset ONU, delete deviceHandler!
3734 return
3735 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003736 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
3737 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003738}
3739
3740func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3741 dh.mutexCollectorFlag.Lock()
3742 dh.collectorIsRunning = flagValue
3743 dh.mutexCollectorFlag.Unlock()
3744}
3745
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003746func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003747 dh.mutexCollectorFlag.RLock()
3748 flagValue := dh.collectorIsRunning
3749 dh.mutexCollectorFlag.RUnlock()
3750 return flagValue
3751}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303752
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303753func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3754 dh.mutextAlarmManagerFlag.Lock()
3755 dh.alarmManagerIsRunning = flagValue
3756 dh.mutextAlarmManagerFlag.Unlock()
3757}
3758
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003759func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303760 dh.mutextAlarmManagerFlag.RLock()
3761 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303762 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303763 dh.mutextAlarmManagerFlag.RUnlock()
3764 return flagValue
3765}
3766
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003767func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303768 logger.Debugf(ctx, "startingAlarmManager")
3769
3770 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003771 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303772 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303773 if stop := <-dh.stopAlarmManager; stop {
3774 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303775 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303776 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003777 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
3778 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05303779 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303780 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003781 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
3782 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05303783 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303784 }
3785}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003786
Girish Gowdrae95687a2021-09-08 16:30:58 -07003787func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
3788 dh.mutexFlowMonitoringRoutineFlag.Lock()
3789 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
3790 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"flag": flag})
3791 dh.isFlowMonitoringRoutineActive[uniID] = flag
3792}
3793
3794func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
3795 dh.mutexFlowMonitoringRoutineFlag.RLock()
3796 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
3797 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
3798 log.Fields{"isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
3799 return dh.isFlowMonitoringRoutineActive[uniID]
3800}
3801
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003802func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
3803 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003804
Maninder7961d722021-06-16 22:10:28 +05303805 connectStatus := voltha.ConnectStatus_UNREACHABLE
3806 operState := voltha.OperStatus_UNKNOWN
3807
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003808 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003809 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003810 logger.Debugw(ctx, "wait for channel signal or timeout",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003811 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003812 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003813 case success := <-dh.chReconcilingFinished:
3814 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003815 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05303816 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003817 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05303818 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003819 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05303820 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003821 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
3822 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05303823 operState = voltha.OperStatus_ACTIVE
3824 } else {
3825 operState = voltha.OperStatus_ACTIVATING
3826 }
3827 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003828 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
3829 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
3830 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05303831 operState = voltha.OperStatus_DISCOVERED
3832 }
3833
3834 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303835 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003836 logger.Debugw(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003837 log.Fields{"device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04003838 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003839 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003840 ConnStatus: connectStatus,
3841 OperStatus: operState,
3842 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05303843 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003844 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05303845 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003846 } else {
Maninderb5187552021-03-23 22:23:42 +05303847 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003848 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05303849
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003850 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05303851 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003852 log.Fields{"device-id": dh.DeviceID})
3853 } else if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninder7961d722021-06-16 22:10:28 +05303854 connectStatus = voltha.ConnectStatus_REACHABLE
3855 }
3856
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003857 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003858 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003859 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003860 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003861 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05303862
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003863 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05303864 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003865 log.Fields{"device-id": dh.DeviceID})
3866 } else if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninder7961d722021-06-16 22:10:28 +05303867 connectStatus = voltha.ConnectStatus_REACHABLE
3868 }
3869
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003870 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05303871
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003872 }
3873 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003874 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003875 dh.mutexReconcilingFlag.Unlock()
3876 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003877 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003878 dh.mutexReconcilingFlag.Lock()
3879 if skipOnuConfig {
3880 dh.reconciling = cSkipOnuConfigReconciling
3881 } else {
3882 dh.reconciling = cOnuConfigReconciling
3883 }
3884 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003885}
3886
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003887func (dh *deviceHandler) StopReconciling(ctx context.Context, success bool) {
3888 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
3889 if dh.IsReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07003890 dh.chReconcilingFinished <- success
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003891 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003892 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003893 }
3894}
3895
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003896func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003897 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003898 defer dh.mutexReconcilingFlag.RUnlock()
3899 return dh.reconciling != cNoReconciling
3900}
3901
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003902func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003903 dh.mutexReconcilingFlag.RLock()
3904 defer dh.mutexReconcilingFlag.RUnlock()
3905 return dh.reconciling == cSkipOnuConfigReconciling
3906}
3907
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003908func (dh *deviceHandler) SetDeviceReason(value uint8) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003909 dh.mutexDeviceReason.Lock()
3910 dh.deviceReason = value
3911 dh.mutexDeviceReason.Unlock()
3912}
3913
3914func (dh *deviceHandler) getDeviceReason() uint8 {
3915 dh.mutexDeviceReason.RLock()
3916 value := dh.deviceReason
3917 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003918 return value
3919}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003920
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003921func (dh *deviceHandler) GetDeviceReasonString() string {
3922 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003923}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003924
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003925func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003926 dh.mutexReadyForOmciConfig.Lock()
3927 dh.readyForOmciConfig = flagValue
3928 dh.mutexReadyForOmciConfig.Unlock()
3929}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003930func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003931 dh.mutexReadyForOmciConfig.RLock()
3932 flagValue := dh.readyForOmciConfig
3933 dh.mutexReadyForOmciConfig.RUnlock()
3934 return flagValue
3935}
Maninder7961d722021-06-16 22:10:28 +05303936
3937func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
3938 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
3939 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003940 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05303941 }
3942
3943 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo7d3c5582021-08-11 18:09:44 -04003944 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003945 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003946 ConnStatus: connectStatus,
3947 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
3948 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05303949 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003950 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05303951 }
3952}
khenaidoo7d3c5582021-08-11 18:09:44 -04003953
3954/*
3955Helper functions to communicate with Core
3956*/
3957
3958func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
3959 cClient, err := dh.coreClient.GetCoreServiceClient()
3960 if err != nil || cClient == nil {
3961 return nil, err
3962 }
3963 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3964 defer cancel()
3965 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
3966 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
3967}
3968
3969func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ic.DeviceStateFilter) error {
3970 cClient, err := dh.coreClient.GetCoreServiceClient()
3971 if err != nil || cClient == nil {
3972 return err
3973 }
3974 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3975 defer cancel()
3976 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
3977 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-state": deviceStateFilter, "error": err})
3978 return err
3979}
3980
3981func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3982 cClient, err := dh.coreClient.GetCoreServiceClient()
3983 if err != nil || cClient == nil {
3984 return err
3985 }
3986 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3987 defer cancel()
3988 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
3989 logger.Debugw(subCtx, "pmconfig-updated-in-core", log.Fields{"pm-configs": pmConfigs, "error": err})
3990 return err
3991}
3992
3993func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
3994 cClient, err := dh.coreClient.GetCoreServiceClient()
3995 if err != nil || cClient == nil {
3996 return err
3997 }
3998 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3999 defer cancel()
4000 _, err = cClient.DeviceUpdate(subCtx, device)
4001 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4002 return err
4003}
4004
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004005func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004006 cClient, err := dh.coreClient.GetCoreServiceClient()
4007 if err != nil || cClient == nil {
4008 return err
4009 }
4010 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4011 defer cancel()
4012 _, err = cClient.PortCreated(subCtx, port)
4013 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4014 return err
4015}
4016
4017func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ic.PortState) error {
4018 cClient, err := dh.coreClient.GetCoreServiceClient()
4019 if err != nil || cClient == nil {
4020 return err
4021 }
4022 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4023 defer cancel()
4024 _, err = cClient.PortStateUpdate(subCtx, portState)
4025 logger.Debugw(subCtx, "port-state-updated-in-core", log.Fields{"port-state": portState, "error": err})
4026 return err
4027}
4028
4029func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ic.DeviceReason) error {
4030 cClient, err := dh.coreClient.GetCoreServiceClient()
4031 if err != nil || cClient == nil {
4032 return err
4033 }
4034 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4035 defer cancel()
4036 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
4037 logger.Debugw(subCtx, "device-reason-updated-in-core", log.Fields{"reason": reason, "error": err})
4038 return err
4039}
4040
4041/*
4042Helper functions to communicate with parent adapter
4043*/
4044
4045func (dh *deviceHandler) getTechProfileInstanceFromParentAdapter(ctx context.Context, parentEndpoint string,
4046 request *ic.TechProfileInstanceRequestMessage) (*ic.TechProfileDownloadMessage, error) {
4047 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4048 if err != nil || pgClient == nil {
4049 return nil, err
4050 }
4051 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4052 defer cancel()
4053 logger.Debugw(subCtx, "get-tech-profile-instance", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4054 return pgClient.GetTechProfileInstance(subCtx, request)
4055}
4056
Girish Gowdrae95687a2021-09-08 16:30:58 -07004057// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4058// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4059func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4060 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4061 dh.setFlowMonitoringIsRunning(uniID, true)
4062 for {
4063 select {
4064 // block on the channel to receive an incoming flow
4065 // process the flow completely before proceeding to handle the next flow
4066 case flowCb := <-dh.flowCbChan[uniID]:
4067 startTime := time.Now()
4068 logger.Debugw(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
4069 respChan := make(chan error)
4070 if flowCb.addFlow {
4071 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4072 } else {
4073 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4074 }
4075 // Block on response and tunnel it back to the caller
4076 *flowCb.respChan <- <-respChan
4077 logger.Debugw(flowCb.ctx, "serial-flow-processor--end",
4078 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4079 case <-dh.stopFlowMonitoringRoutine[uniID]:
4080 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4081 dh.setFlowMonitoringIsRunning(uniID, false)
4082 return
4083 }
4084 }
4085}
4086
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004087func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ic.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004088 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4089 if err != nil || pgClient == nil {
4090 return err
4091 }
4092 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4093 defer cancel()
4094 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4095 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4096 if err != nil {
4097 logger.Errorw(ctx, "omci-failure", log.Fields{"request": request, "error": err, "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
4098 }
4099 return err
4100}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004101
4102// GetDeviceID - TODO: add comment
4103func (dh *deviceHandler) GetDeviceID() string {
4104 return dh.DeviceID
4105}
4106
4107// GetProxyAddressID - TODO: add comment
4108func (dh *deviceHandler) GetProxyAddressID() string {
4109 return dh.device.ProxyAddress.GetDeviceId()
4110}
4111
4112// GetProxyAddressType - TODO: add comment
4113func (dh *deviceHandler) GetProxyAddressType() string {
4114 return dh.device.ProxyAddress.GetDeviceType()
4115}
4116
4117// GetProxyAddress - TODO: add comment
4118func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4119 return dh.device.ProxyAddress
4120}
4121
4122// GetEventProxy - TODO: add comment
4123func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4124 return dh.EventProxy
4125}
4126
4127// GetOmciTimeout - TODO: add comment
4128func (dh *deviceHandler) GetOmciTimeout() int {
4129 return dh.pOpenOnuAc.omciTimeout
4130}
4131
4132// GetAlarmAuditInterval - TODO: add comment
4133func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4134 return dh.pOpenOnuAc.alarmAuditInterval
4135}
4136
4137// GetDlToOnuTimeout4M - TODO: add comment
4138func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4139 return dh.pOpenOnuAc.dlToOnuTimeout4M
4140}
4141
4142// GetUniEntityMap - TODO: add comment
4143func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4144 return &dh.uniEntityMap
4145}
4146
4147// GetPonPortNumber - TODO: add comment
4148func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4149 return &dh.ponPortNumber
4150}
4151
4152// GetUniVlanConfigFsm - TODO: add comment
4153func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004154 dh.lockVlanConfig.RLock()
4155 value := dh.UniVlanConfigFsmMap[uniID]
4156 dh.lockVlanConfig.RUnlock()
4157 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004158}
4159
4160// GetOnuAlarmManager - TODO: add comment
4161func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4162 return dh.pAlarmMgr
4163}
4164
4165// GetOnuMetricsManager - TODO: add comment
4166func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4167 return dh.pOnuMetricsMgr
4168}
4169
4170// GetOnuTP - TODO: add comment
4171func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4172 return dh.pOnuTP
4173}
4174
4175// GetBackendPathPrefix - TODO: add comment
4176func (dh *deviceHandler) GetBackendPathPrefix() string {
4177 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4178}
4179
4180// GetOnuIndication - TODO: add comment
4181func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4182 return dh.pOnuIndication
4183}
4184
4185// RLockMutexDeletionInProgressFlag - TODO: add comment
4186func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4187 dh.mutexDeletionInProgressFlag.RLock()
4188}
4189
4190// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4191func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4192 dh.mutexDeletionInProgressFlag.RUnlock()
4193}
4194
4195// GetDeletionInProgress - TODO: add comment
4196func (dh *deviceHandler) GetDeletionInProgress() bool {
4197 return dh.deletionInProgress
4198}
4199
4200// GetPmConfigs - TODO: add comment
4201func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4202 return dh.pmConfigs
4203}
4204
4205// GetDeviceType - TODO: add comment
4206func (dh *deviceHandler) GetDeviceType() string {
4207 return dh.DeviceType
4208}
4209
4210// GetLogicalDeviceID - TODO: add comment
4211func (dh *deviceHandler) GetLogicalDeviceID() string {
4212 return dh.logicalDeviceID
4213}
4214
4215// GetDevice - TODO: add comment
4216func (dh *deviceHandler) GetDevice() *voltha.Device {
4217 return dh.device
4218}
4219
4220// GetMetricsEnabled - TODO: add comment
4221func (dh *deviceHandler) GetMetricsEnabled() bool {
4222 return dh.pOpenOnuAc.MetricsEnabled
4223}
4224
4225// InitPmConfigs - TODO: add comment
4226func (dh *deviceHandler) InitPmConfigs() {
4227 dh.pmConfigs = &voltha.PmConfigs{}
4228}
4229
4230// GetUniPortMask - TODO: add comment
4231func (dh *deviceHandler) GetUniPortMask() int {
4232 return dh.pOpenOnuAc.config.UniPortMask
4233}