blob: 87a74106762ec767991832f247cc1b1272a485eb [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000017//Package core provides the utility for onu devices, flows and statistics
18package core
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000019
20import (
21 "context"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000022 "errors"
23 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000024 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000025 "sync"
26 "time"
27
khenaidoo7d3c5582021-08-11 18:09:44 -040028 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/config"
mpagenko1f8e8822021-06-25 14:10:21 +000029
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000030 "github.com/gogo/protobuf/proto"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000031 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000032 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040033 "github.com/opencord/voltha-lib-go/v7/pkg/db"
34 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
35 flow "github.com/opencord/voltha-lib-go/v7/pkg/flows"
36 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
37 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Mahir Gunyelcb128ae2021-10-06 09:42:05 -070038 platform "github.com/opencord/voltha-lib-go/v7/pkg/platform"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000039 almgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/almgr"
40 avcfg "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/avcfg"
41 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
42 mib "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/mib"
43 otst "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/omcitst"
44 pmmgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/pmmgr"
45 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/swupg"
46 uniprt "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/uniprt"
khenaidoo7d3c5582021-08-11 18:09:44 -040047 vc "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo42dcdfd2021-10-19 17:34:12 -040048 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040049 "github.com/opencord/voltha-protos/v5/go/extension"
khenaidoo42dcdfd2021-10-19 17:34:12 -040050 ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040051 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
mpagenko59862f02021-10-11 08:53:18 +000052 "github.com/opencord/voltha-protos/v5/go/openolt"
khenaidoo7d3c5582021-08-11 18:09:44 -040053 oop "github.com/opencord/voltha-protos/v5/go/openolt"
mpagenko59862f02021-10-11 08:53:18 +000054 "github.com/opencord/voltha-protos/v5/go/tech_profile"
khenaidoo7d3c5582021-08-11 18:09:44 -040055 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000056)
57
mpagenko38662d02021-08-11 09:45:19 +000058// Constants for timeouts
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000059const (
mpagenko38662d02021-08-11 09:45:19 +000060 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000061)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000062
mpagenko1cc3cb42020-07-27 15:24:38 +000063const (
64 // events of Device FSM
65 devEvDeviceInit = "devEvDeviceInit"
66 devEvGrpcConnected = "devEvGrpcConnected"
67 devEvGrpcDisconnected = "devEvGrpcDisconnected"
68 devEvDeviceUpInd = "devEvDeviceUpInd"
69 devEvDeviceDownInd = "devEvDeviceDownInd"
70)
71const (
72 // states of Device FSM
73 devStNull = "devStNull"
74 devStDown = "devStDown"
75 devStInit = "devStInit"
76 devStConnected = "devStConnected"
77 devStUp = "devStUp"
78)
79
Holger Hildebrandt24d51952020-05-04 14:03:42 +000080//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
81const (
Himani Chawla4d908332020-08-31 12:30:20 +053082 pon = voltha.EventSubCategory_PON
83 //olt = voltha.EventSubCategory_OLT
84 //ont = voltha.EventSubCategory_ONT
85 //onu = voltha.EventSubCategory_ONU
86 //nni = voltha.EventSubCategory_NNI
87 //service = voltha.EventCategory_SERVICE
88 //security = voltha.EventCategory_SECURITY
89 equipment = voltha.EventCategory_EQUIPMENT
90 //processing = voltha.EventCategory_PROCESSING
91 //environment = voltha.EventCategory_ENVIRONMENT
92 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000093)
94
95const (
96 cEventObjectType = "ONU"
97)
98const (
99 cOnuActivatedEvent = "ONU_ACTIVATED"
100)
101
mpagenkof1fc3862021-02-16 10:09:52 +0000102type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000103 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000104 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000105}
106
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000107var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
108 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
109 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
110 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
111 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
112 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
113 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
114 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
115 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000116}
117
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000118const (
119 cNoReconciling = iota
120 cOnuConfigReconciling
121 cSkipOnuConfigReconciling
122)
123
Girish Gowdrae95687a2021-09-08 16:30:58 -0700124// FlowCb is the flow control block containing flow add/delete information along with a response channel
125type FlowCb struct {
126 ctx context.Context // Flow handler context
127 addFlow bool // if true flow to be added, else removed
128 flowItem *of.OfpFlowStats
129 uniPort *cmn.OnuUniPort
khenaidoo42dcdfd2021-10-19 17:34:12 -0400130 flowMetaData *of.FlowMetadata
Girish Gowdrae95687a2021-09-08 16:30:58 -0700131 respChan *chan error // channel to report the Flow handling error
132}
133
Himani Chawla6d2ae152020-09-02 13:11:20 +0530134//deviceHandler will interact with the ONU ? device.
135type deviceHandler struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000136 DeviceID string
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000137 DeviceType string
138 adminState string
139 device *voltha.Device
140 logicalDeviceID string
141 ProxyAddressID string
142 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530143 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000144 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000145
khenaidoo7d3c5582021-08-11 18:09:44 -0400146 coreClient *vgrpc.Client
147 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000148
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800149 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400150 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800151
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000152 pOpenOnuAc *OpenONUAC
153 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530154 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000155 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000156 pOnuOmciDevice *mib.OnuDeviceEntry
157 pOnuTP *avcfg.OnuUniTechProf
158 pOnuMetricsMgr *pmmgr.OnuMetricsManager
159 pAlarmMgr *almgr.OnuAlarmManager
160 pSelfTestHdlr *otst.SelfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000161 exitChannel chan int
162 lockDevice sync.RWMutex
163 pOnuIndication *oop.OnuIndication
164 deviceReason uint8
165 mutexDeviceReason sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000166 pLockStateFsm *uniprt.LockStateFsm
167 pUnlockStateFsm *uniprt.LockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000168
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000169 //flowMgr *OpenOltFlowMgr
170 //eventMgr *OpenOltEventMgr
171 //resourceMgr *rsrcMgr.OpenOltResourceMgr
172
173 //discOnus sync.Map
174 //onus sync.Map
175 //portStats *OpenOltStatisticsMgr
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000176 collectorIsRunning bool
177 mutexCollectorFlag sync.RWMutex
178 stopCollector chan bool
179 alarmManagerIsRunning bool
180 mutextAlarmManagerFlag sync.RWMutex
181 stopAlarmManager chan bool
182 stopHeartbeatCheck chan bool
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000183 uniEntityMap cmn.OnuUniPortMap
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000184 mutexKvStoreContext sync.Mutex
185 lockVlanConfig sync.RWMutex
mpagenkobc4170a2021-08-17 16:42:10 +0000186 lockVlanAdd sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000187 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000188 lockUpgradeFsm sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000189 pOnuUpradeFsm *swupg.OnuUpgradeFsm
mpagenko59862f02021-10-11 08:53:18 +0000190 upgradeCanceled bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000191 reconciling uint8
192 mutexReconcilingFlag sync.RWMutex
193 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000194 mutexReadyForOmciConfig sync.RWMutex
195 readyForOmciConfig bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000196 deletionInProgress bool
197 mutexDeletionInProgressFlag sync.RWMutex
mpagenko38662d02021-08-11 09:45:19 +0000198 pLastUpgradeImageState *voltha.ImageState
199 upgradeFsmChan chan struct{}
Girish Gowdrae95687a2021-09-08 16:30:58 -0700200
201 flowCbChan []chan FlowCb
202 mutexFlowMonitoringRoutineFlag sync.RWMutex
203 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
204 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000205}
206
Himani Chawla6d2ae152020-09-02 13:11:20 +0530207//newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400208func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530209 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400210 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000211 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400212 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000213 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000214 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000215 dh.DeviceType = cloned.Type
216 dh.adminState = "up"
217 dh.device = cloned
218 dh.pOpenOnuAc = adapter
219 dh.exitChannel = make(chan int, 1)
220 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000221 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000222 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000223 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530224 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530225 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000226 dh.stopHeartbeatCheck = make(chan bool, 2)
227 //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 +0000228 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000229 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000230 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000231 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000232 dh.lockUpgradeFsm = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000233 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000234 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000235 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000236 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000237 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000238 dh.pLastUpgradeImageState = &voltha.ImageState{
239 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
240 Reason: voltha.ImageState_UNKNOWN_ERROR,
241 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
242 }
243 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000244
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800245 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
246 dh.pmConfigs = cloned.PmConfigs
247 } /* else {
248 // will be populated when onu_metrics_mananger is initialized.
249 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800250
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000251 // Device related state machine
252 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000253 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000254 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000255 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
256 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
257 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
258 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
259 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000260 },
261 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000262 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
263 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
264 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
265 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
266 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
267 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
268 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
269 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000270 },
271 )
mpagenkoaf801632020-07-03 10:00:42 +0000272
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000273 return &dh
274}
275
Himani Chawla6d2ae152020-09-02 13:11:20 +0530276// start save the device to the data model
277func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000278 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000279 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000280 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000281}
282
Himani Chawla4d908332020-08-31 12:30:20 +0530283/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000284// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530285func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286 logger.Debug("stopping-device-handler")
287 dh.exitChannel <- 1
288}
Himani Chawla4d908332020-08-31 12:30:20 +0530289*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000290
291// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530292// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000293
Girish Gowdrae0140f02021-02-02 16:55:09 -0800294//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530295func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400296 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297
dbainbri4d3a0dc2020-12-02 00:33:42 +0000298 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000299 if dh.pDeviceStateFsm.Is(devStNull) {
300 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000301 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000302 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000303 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800304 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
305 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800306 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400307 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000308 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800309 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800310 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000311 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000312 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000313 }
314
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000315}
316
khenaidoo42dcdfd2021-10-19 17:34:12 -0400317func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000318 /* 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 +0530319 //assuming omci message content is hex coded!
320 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000321 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000322 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000323 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000324 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530325 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000326 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000327 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000328 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400329 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 +0530330 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000331 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
332 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530333}
334
khenaidoo42dcdfd2021-10-19 17:34:12 -0400335func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000336 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000337
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000338 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000339 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000340 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
341 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000342 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530343 if dh.pOnuTP == nil {
344 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000345 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000346 log.Fields{"device-id": dh.DeviceID})
347 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530348 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000349 if !dh.IsReadyForOmciConfig() {
350 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
351 "device-state": dh.GetDeviceReasonString()})
352 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530353 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000354 //previous state test here was just this one, now extended for more states to reject the SetRequest:
355 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
356 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530357
Himani Chawla26e555c2020-08-31 12:30:20 +0530358 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000359 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
360 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000361 dh.pOnuTP.LockTpProcMutex()
362 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000363
364 if techProfMsg.UniId > 255 {
365 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000366 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000367 }
368 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000369 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800370 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700371 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800372 return err
373 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700374 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000375
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000376 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530377
Girish Gowdra50e56422021-06-01 16:46:04 -0700378 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400379 case *ia.TechProfileDownloadMessage_TpInstance:
Girish Gowdra50e56422021-06-01 16:46:04 -0700380 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
381 // if there has been some change for some uni TechProfilePath
382 //in order to allow concurrent calls to other dh instances we do not wait for execution here
383 //but doing so we can not indicate problems to the caller (who does what with that then?)
384 //by now we just assume straightforward successful execution
385 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
386 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530387
Girish Gowdra50e56422021-06-01 16:46:04 -0700388 // deadline context to ensure completion of background routines waited for
389 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
390 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
391 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000392
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000393 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700394
395 var wg sync.WaitGroup
396 wg.Add(1) // for the 1 go routine to finish
397 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000398 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700399 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000400 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
401 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 -0700402 return tpErr
403 }
404 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
405 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000406 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700407 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000408 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700409 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000410 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
411 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 -0700412 return kvErr
413 }
414 return nil
415 default:
416 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"tp-path": techProfMsg.TpInstancePath})
417 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700418 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530419 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000420 // no change, nothing really to do - return success
Girish Gowdra50e56422021-06-01 16:46:04 -0700421 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 +0530422 return nil
423}
424
khenaidoo42dcdfd2021-10-19 17:34:12 -0400425func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000426 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530427
428 if dh.pOnuTP == nil {
429 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000430 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000431 log.Fields{"device-id": dh.DeviceID})
432 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530433 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530434 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000435 dh.pOnuTP.LockTpProcMutex()
436 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530437
mpagenko0f543222021-11-03 16:24:14 +0000438 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
439 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
440 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000441 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000442 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000443 }
444 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000445 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800446 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000447 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
448 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800449 return err
450 }
mpagenko0f543222021-11-03 16:24:14 +0000451 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
452 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000453 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000454
Mahir Gunyel9545be22021-07-04 15:53:16 -0700455 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000456 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000457
Himani Chawla26e555c2020-08-31 12:30:20 +0530458}
459
khenaidoo42dcdfd2021-10-19 17:34:12 -0400460func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000461 logger.Infow(ctx, "delete-tcont-request start", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000462
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000463 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000464 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000465 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
466 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000467 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530468 if dh.pOnuTP == nil {
469 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000470 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000471 log.Fields{"device-id": dh.DeviceID})
472 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530473 }
474
Himani Chawla26e555c2020-08-31 12:30:20 +0530475 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000476 dh.pOnuTP.LockTpProcMutex()
477 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000478
mpagenko0f543222021-11-03 16:24:14 +0000479 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
480 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
481 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000482 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000483 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000484 }
485 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700486 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000487 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800488 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000489 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
490 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800491 return err
492 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000493 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 +0000494
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000495 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530496
Mahir Gunyel9545be22021-07-04 15:53:16 -0700497 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000498 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000499
Mahir Gunyel9545be22021-07-04 15:53:16 -0700500}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000501
Mahir Gunyel9545be22021-07-04 15:53:16 -0700502func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000503 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
504 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700505 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000506 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
507 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530508 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700509 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000510 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700511 resourceName = "Gem"
512 } else {
513 resourceName = "Tcont"
514 }
515
516 // deadline context to ensure completion of background routines waited for
517 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
518 dctx, cancel := context.WithDeadline(context.Background(), deadline)
519
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000520 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700521
522 var wg sync.WaitGroup
523 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000524 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700525 resource, entryID, &wg)
526 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000527 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
528 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700529 return err
530 }
531
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000532 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
533 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
534 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
535 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700536 var wg2 sync.WaitGroup
537 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
538 wg2.Add(1)
539 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000540 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
541 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700542 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000543 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
544 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700545 return err
546 }
547 }
548 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000549 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700550 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530551 return nil
552}
553
mpagenkodff5dda2020-08-28 11:52:01 +0000554//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000555func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400556 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400557 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700558 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
559 var errorsList []error
560 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000561 //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 +0000562 if apOfFlowChanges.ToRemove != nil {
563 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000564 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000565 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000566 "device-id": dh.DeviceID})
567 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700568 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000569 continue
570 }
571 flowInPort := flow.GetInPort(flowItem)
572 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000573 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
574 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700575 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000576 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000577 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000578 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000579 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000580 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000581 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000582 continue
583 } else {
584 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000585 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000586 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
587 loUniPort = uniPort
588 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000589 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000590 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000591 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000592 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700593 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000594 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000595 }
596 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000597 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000598 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
599 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700600
601 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
602 // Step1 : Fill flowControlBlock
603 // Step2 : Push the flowControlBlock to ONU channel
604 // Step3 : Wait on response channel for response
605 // Step4 : Return error value
606 startTime := time.Now()
607 respChan := make(chan error)
608 flowCb := FlowCb{
609 ctx: ctx,
610 addFlow: false,
611 flowItem: flowItem,
612 flowMetaData: nil,
613 uniPort: loUniPort,
614 respChan: &respChan,
615 }
616 dh.flowCbChan[loUniPort.UniID] <- flowCb
617 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
618 // Wait on the channel for flow handlers return value
619 retError = <-respChan
620 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
621 if retError != nil {
622 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
623 log.Fields{"device-id": dh.DeviceID, "error": retError})
624 errorsList = append(errorsList, retError)
625 continue
626 }
627 } else {
628 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
629 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000630 }
631 }
632 }
633 }
mpagenko01e726e2020-10-23 09:45:29 +0000634 if apOfFlowChanges.ToAdd != nil {
635 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
636 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000637 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000638 "device-id": dh.DeviceID})
639 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700640 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000641 continue
642 }
643 flowInPort := flow.GetInPort(flowItem)
644 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000645 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
646 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700647 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000648 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000649 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000650 } else if flowInPort == dh.ponPortNumber {
651 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000652 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000653 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000654 continue
655 } else {
656 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000657 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000658 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
659 loUniPort = uniPort
660 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000661 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000662 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000663 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000664 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700665 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000666 continue
mpagenko01e726e2020-10-23 09:45:29 +0000667 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000668 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
669 // if not, we just throw some error here to have an indication about that, if we really need to support that
670 // then we would need to create some means to activate the internal stored flows
671 // after the device gets active automatically (and still with its dependency to the TechProfile)
672 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
673 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000674 if !dh.IsReadyForOmciConfig() {
675 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
676 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700677 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
678 errorsList = append(errorsList, retError)
679 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000680 }
681
mpagenko01e726e2020-10-23 09:45:29 +0000682 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000683 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000684 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
685 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700686 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
687 // Step1 : Fill flowControlBlock
688 // Step2 : Push the flowControlBlock to ONU channel
689 // Step3 : Wait on response channel for response
690 // Step4 : Return error value
691 startTime := time.Now()
692 respChan := make(chan error)
693 flowCb := FlowCb{
694 ctx: ctx,
695 addFlow: true,
696 flowItem: flowItem,
697 flowMetaData: apFlowMetaData,
698 uniPort: loUniPort,
699 respChan: &respChan,
700 }
701 dh.flowCbChan[loUniPort.UniID] <- flowCb
702 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
703 // Wait on the channel for flow handlers return value
704 retError = <-respChan
705 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
706 if retError != nil {
707 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
708 log.Fields{"device-id": dh.DeviceID, "error": retError})
709 errorsList = append(errorsList, retError)
710 continue
711 }
712 } else {
713 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
714 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000715 }
716 }
717 }
718 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700719 if len(errorsList) > 0 {
720 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
721 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
722 }
723 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000724}
725
Himani Chawla6d2ae152020-09-02 13:11:20 +0530726//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000727//following are the expected device states after this activity:
728//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
729// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000730func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
731 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000732
mpagenko900ee4b2020-10-12 11:56:34 +0000733 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000734 //note that disableDevice sequences in some 'ONU active' state may yield also
735 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000736 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000737 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000738 //disable-device shall be just a UNi/ONU-G related admin state setting
739 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000740
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000741 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000742 // disable UNI ports/ONU
743 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
744 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000745 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000746 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000747 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000748 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000749 }
750 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000751 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000752 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -0400753 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000754 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -0400755 ConnStatus: voltha.ConnectStatus_REACHABLE,
756 OperStatus: voltha.OperStatus_UNKNOWN,
757 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000758 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000759 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000760 }
mpagenko01e726e2020-10-23 09:45:29 +0000761 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000762
763 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000764 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000765 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300766 }
767}
768
Himani Chawla6d2ae152020-09-02 13:11:20 +0530769//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000770func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
771 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000772
mpagenkoaa3afe92021-05-21 16:20:58 +0000773 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000774 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
775 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
776 // for real ONU's that should have nearly no influence
777 // Note that for real ONU's there is anyway a problematic situation with following sequence:
778 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
779 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
780 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000781 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000782
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000783 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000784 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000785 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000786 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000787 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000788 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000789 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000790 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300791}
792
dbainbri4d3a0dc2020-12-02 00:33:42 +0000793func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000794 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000795
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000796 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000797 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000798 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000799 return
800 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000801 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000802 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000803 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000804 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000805 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000806 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000807 dh.StopReconciling(ctx, false)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000808 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000809 }
Himani Chawla4d908332020-08-31 12:30:20 +0530810 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000811 pDevEntry.MutexPersOnuConfig.RLock()
812 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
813 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
814 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
815 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
816 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000817 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000818}
819
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000820func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) {
821 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000822
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000823 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000824 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000825 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
826 if !dh.IsSkipOnuConfigReconciling() {
827 dh.StopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000828 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000829 return
830 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000831 dh.pOnuTP.LockTpProcMutex()
832 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000833
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000834 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000835 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000836 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
837 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000838 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000839 log.Fields{"device-id": dh.DeviceID})
840 if !dh.IsSkipOnuConfigReconciling() {
841 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000842 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000843 return
844 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000845 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700846 techProfsFound := false
847 techProfInstLoadFailed := false
848outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000849 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000850 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
851 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000852 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000853 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000854 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000855 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000856 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
857 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000858 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000859 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000860 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700861 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800862 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700863 // Request the TpInstance again from the openolt adapter in case of reconcile
khenaidoo7d3c5582021-08-11 18:09:44 -0400864 iaTechTpInst, err := dh.getTechProfileInstanceFromParentAdapter(ctx,
865 dh.device.ProxyAddress.AdapterEndpoint,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400866 &ia.TechProfileInstanceRequestMessage{
khenaidoo7d3c5582021-08-11 18:09:44 -0400867 DeviceId: dh.device.Id,
868 TpInstancePath: uniData.PersTpPathMap[tpID],
869 ParentDeviceId: dh.parentID,
870 ParentPonPort: dh.device.ParentPortNo,
871 OnuId: dh.device.ProxyAddress.OnuId,
872 UniId: uint32(uniData.PersUniID),
873 })
Girish Gowdra50e56422021-06-01 16:46:04 -0700874 if err != nil || iaTechTpInst == nil {
875 logger.Errorw(ctx, "error fetching tp instance",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000876 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 -0700877 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
878 break outerLoop
879 }
880 var tpInst tech_profile.TechProfileInstance
881 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400882 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700883 tpInst = *techTpInst.TpInstance
mpagenko2dc896e2021-08-02 12:03:59 +0000884 logger.Debugw(ctx, "received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000885 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700886 default: // do not support epon or other tech
mpagenko2dc896e2021-08-02 12:03:59 +0000887 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000888 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700889 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
890 break outerLoop
891 }
892
Girish Gowdra041dcb32020-11-16 16:54:30 -0800893 // deadline context to ensure completion of background routines waited for
894 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
895 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000896 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000897
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000898 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800899 var wg sync.WaitGroup
900 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000901 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000902 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000903 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
904 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700905 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
906 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800907 }
mpagenko2dc896e2021-08-02 12:03:59 +0000908 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000909 if len(uniData.PersFlowParams) != 0 {
910 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000911 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000912 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000913 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000914 } // for all UNI entries from SOnuPersistentData
915 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
916 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000917 }
mpagenko2dc896e2021-08-02 12:03:59 +0000918
919 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
920 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
921}
922
923func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
924 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
925 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000926 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000927 log.Fields{"device-id": dh.DeviceID})
928 if !dh.IsSkipOnuConfigReconciling() {
929 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000930 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000931 return
932 }
mpagenko2dc896e2021-08-02 12:03:59 +0000933 if abTechProfInstLoadFailed {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000934 dh.SetDeviceReason(cmn.DrTechProfileConfigDownloadFailed)
935 dh.StopReconciling(ctx, false)
Girish Gowdra50e56422021-06-01 16:46:04 -0700936 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000937 } else if dh.IsSkipOnuConfigReconciling() {
938 dh.SetDeviceReason(cmn.DrTechProfileConfigDownloadSuccess)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000939 }
mpagenko2dc896e2021-08-02 12:03:59 +0000940 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000941 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000942 log.Fields{"device-id": dh.DeviceID})
943 if !dh.IsSkipOnuConfigReconciling() {
944 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000945 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000946 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000947}
948
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000949func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
950 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000951
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000952 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000953 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000954 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
955 if !dh.IsSkipOnuConfigReconciling() {
956 dh.StopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000957 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000958 return
959 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000960
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000961 pDevEntry.MutexPersOnuConfig.RLock()
962 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
963 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000964 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000965 log.Fields{"device-id": dh.DeviceID})
966 if !dh.IsSkipOnuConfigReconciling() {
967 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000968 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000969 return
970 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000971 flowsFound := false
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000972 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000973 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
974 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000975 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000976 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000977 continue
978 }
979 if len(uniData.PersTpPathMap) == 0 {
980 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000981 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000982 // It doesn't make sense to configure any flows if no TPs are available
983 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000984 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000985 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
986 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000987 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000988 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000989
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000990 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000991 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -0700992 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000993 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000994 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
995 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
996 if !dh.IsSkipOnuConfigReconciling() {
997 dh.StopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000998 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000999 return
1000 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001001 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001002 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001003 flowsProcessed := 0
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001004 pDevEntry.SetReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001005 for _, flowData := range uniData.PersFlowParams {
mpagenko2dc896e2021-08-02 12:03:59 +00001006 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001007 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001008 if flowsProcessed == len(uniData.PersFlowParams)-1 {
1009 lastFlowToReconcile = true
1010 }
mpagenko01e726e2020-10-23 09:45:29 +00001011 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenko7d14de12021-07-27 08:31:56 +00001012 dh.lockVlanConfig.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001013 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001014 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +00001015 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Girish Gowdrae95687a2021-09-08 16:30:58 -07001016 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter, nil); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001017 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001018 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001019 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001020 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00001021 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Girish Gowdrae95687a2021-09-08 16:30:58 -07001022 uint8(flowData.VlanRuleParams.SetPcp), cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001023 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001024 }
1025 }
mpagenko7d14de12021-07-27 08:31:56 +00001026 dh.lockVlanConfig.Unlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001027 flowsProcessed++
mpagenko2dc896e2021-08-02 12:03:59 +00001028 } //for all flows of this UNI
1029 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001030 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID, "flowsProcessed": flowsProcessed,
1031 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1032 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001033 // this can't be used as global finished reconciling flag because
1034 // assumes is getting called before the state machines for the last flow is completed,
1035 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001036 //dh.SetReconcilingFlows(false)
1037 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1038 } // for all UNI entries from SOnuPersistentData
1039 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001040
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001041 if !flowsFound {
1042 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001043 log.Fields{"device-id": dh.DeviceID})
1044 if !dh.IsSkipOnuConfigReconciling() {
1045 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001046 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001047 return
1048 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001049 if dh.IsSkipOnuConfigReconciling() {
1050 dh.SetDeviceReason(cmn.DrOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001051 }
1052}
1053
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001054func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001055 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.DeviceID})
1056 dh.StopReconciling(ctx, true)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001057}
1058
dbainbri4d3a0dc2020-12-02 00:33:42 +00001059func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001060 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001061
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001062 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001063 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001064 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001065 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001066 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001067 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001068
1069 // deadline context to ensure completion of background routines waited for
1070 //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 +05301071 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001072 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001073
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001074 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001075
1076 var wg sync.WaitGroup
1077 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001078 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001079 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001080
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001081 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001082 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001083}
1084
mpagenko15ff4a52021-03-02 10:09:20 +00001085//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1086// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001087// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001088//was and is called in background - error return does not make sense
1089func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001090 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001091 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001092 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001093 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001094 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001095 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301096 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001097 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001098 return
Himani Chawla4d908332020-08-31 12:30:20 +05301099 }
mpagenko01e726e2020-10-23 09:45:29 +00001100
1101 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001102 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001103
dbainbri4d3a0dc2020-12-02 00:33:42 +00001104 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001105 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04001106 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001107 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001108 ConnStatus: voltha.ConnectStatus_REACHABLE,
1109 OperStatus: voltha.OperStatus_DISCOVERED,
1110 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001111 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001112 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001113 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001114 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001115 if err := dh.deviceReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001116 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001117 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001118 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001119 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1120 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1121 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1122 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001123}
1124
mpagenkoc8bba412021-01-15 15:38:44 +00001125//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001126// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001127func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001128 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001129 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001130 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001131
1132 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001133 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001134 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001135 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1136 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001137 }
1138
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001139 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001140 var inactiveImageID uint16
1141 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1142 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001143 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1144 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001145 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001146 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001147 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001148 if err == nil {
1149 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1150 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001151 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001152 }
1153 } else {
1154 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001155 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001156 }
mpagenko15ff4a52021-03-02 10:09:20 +00001157 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001158 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001159 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001160 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1161 dh.upgradeCanceled = true
1162 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1163 }
mpagenko38662d02021-08-11 09:45:19 +00001164 //no effort spent anymore for the old API to automatically cancel and restart the download
1165 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001166 }
mpagenko15ff4a52021-03-02 10:09:20 +00001167 } else {
1168 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001169 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001170 }
1171 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001172 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1173 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001174 }
1175 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001176}
1177
mpagenkoc26d4c02021-05-06 14:27:57 +00001178//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1179// after the OnuImage has been downloaded to the adapter, called in background
1180func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001181 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001182
1183 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001184 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001185 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001186 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001187 return
1188 }
1189
1190 var inactiveImageID uint16
1191 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1192 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001193 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001194
mpagenko59862f02021-10-11 08:53:18 +00001195 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001196 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001197 // but must be still locked at calling createOnuUpgradeFsm
1198 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1199 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1200 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001201 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1202 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001203 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001204 //flush the remove upgradeFsmChan channel
1205 select {
1206 case <-dh.upgradeFsmChan:
1207 logger.Debug(ctx, "flushed-upgrade-fsm-channel")
1208 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001209 }
mpagenko59862f02021-10-11 08:53:18 +00001210 dh.lockUpgradeFsm.Unlock()
1211 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1212 dh.upgradeCanceled = true
1213 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1214 }
mpagenko38662d02021-08-11 09:45:19 +00001215 select {
1216 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001217 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001218 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1219 return
1220 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001221 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001222 }
mpagenko59862f02021-10-11 08:53:18 +00001223 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001224 }
mpagenko38662d02021-08-11 09:45:19 +00001225
1226 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001227 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001228 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001229 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001230 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001231 if err == nil {
1232 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1233 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1234 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001235 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001236 return
1237 }
mpagenko38662d02021-08-11 09:45:19 +00001238 } else {
1239 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001240 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001241 }
1242 return
1243 }
1244 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001245 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001246}
1247
1248//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001249func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1250 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001251 var err error
1252 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1253 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1254 // 2.) activation of the inactive image
1255
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001256 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001257 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001258 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1259 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001260 }
1261 dh.lockUpgradeFsm.RLock()
1262 if dh.pOnuUpradeFsm != nil {
1263 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001264 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001265 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001266 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1267 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001268 }
mpagenko59862f02021-10-11 08:53:18 +00001269 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1270 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1271 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1272 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001273 // use the OnuVendor identification from this device for the internal unique name
1274 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001275 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001276 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001277 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001278 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001279 "device-id": dh.DeviceID, "error": err})
1280 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001281 }
mpagenko183647c2021-06-08 15:25:04 +00001282 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001283 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001284 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001285 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001286 } //else
1287 dh.lockUpgradeFsm.RUnlock()
1288
1289 // 2.) check if requested image-version equals the inactive one and start its activation
1290 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1291 var inactiveImageID uint16
1292 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1293 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001294 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1295 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001296 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001297 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001298 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001299 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001300 if err == nil {
1301 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1302 inactiveImageID, aCommitRequest); err != nil {
1303 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001304 "device-id": dh.DeviceID, "error": err})
1305 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001306 }
1307 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001308 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001309 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001310 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001311 } //else
1312 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001313 "device-id": dh.DeviceID, "error": err})
1314 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001315}
1316
1317//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001318func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1319 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001320 var err error
1321 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1322 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1323 // 2.) commitment of the active image
1324
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001325 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001326 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001327 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1328 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001329 }
1330 dh.lockUpgradeFsm.RLock()
1331 if dh.pOnuUpradeFsm != nil {
1332 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001333 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001334 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001335 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1336 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001337 }
mpagenko59862f02021-10-11 08:53:18 +00001338 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1339 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1340 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1341 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001342 // use the OnuVendor identification from this device for the internal unique name
1343 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001344 // 1.) check a started upgrade process and relay the commitment request to it
1345 // the running upgrade may be based either on the imageIdentifier (started from download)
1346 // or on the imageVersion (started from pure activation)
1347 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1348 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001349 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001350 "device-id": dh.DeviceID, "error": err})
1351 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001352 }
mpagenko183647c2021-06-08 15:25:04 +00001353 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001354 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001355 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001356 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001357 } //else
1358 dh.lockUpgradeFsm.RUnlock()
1359
mpagenko183647c2021-06-08 15:25:04 +00001360 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001361 var activeImageID uint16
1362 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1363 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001364 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1365 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001366 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001367 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001368 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001369 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001370 if err == nil {
1371 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1372 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001373 "device-id": dh.DeviceID, "error": err})
1374 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001375 }
1376 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001377 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001378 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001379 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001380 } //else
1381 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001382 "device-id": dh.DeviceID, "error": err})
1383 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001384}
1385
mpagenkoaa3afe92021-05-21 16:20:58 +00001386func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001387 aVersion string) *voltha.ImageState {
1388 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001389 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001390 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001391 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001392 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1393 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1394 if aVersion == dh.pLastUpgradeImageState.Version {
1395 pImageState = dh.pLastUpgradeImageState
1396 } else { //state request for an image version different from last processed image version
1397 pImageState = &voltha.ImageState{
1398 Version: aVersion,
1399 //we cannot state something concerning this version
1400 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1401 Reason: voltha.ImageState_NO_ERROR,
1402 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1403 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001404 }
1405 }
mpagenko38662d02021-08-11 09:45:19 +00001406 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001407}
1408
1409func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1410 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001411 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001412 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001413 dh.lockUpgradeFsm.RLock()
1414 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001415 dh.lockUpgradeFsm.RUnlock()
1416 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001417 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001418 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1419 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1420 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1421 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1422 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1423 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001424 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1425 dh.upgradeCanceled = true
1426 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1427 }
mpagenko45586762021-10-01 08:30:22 +00001428 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001429 } else {
mpagenko45586762021-10-01 08:30:22 +00001430 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001431 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1432 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1433 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1434 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1435 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1436 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001437 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1438 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001439 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1440 //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 +00001441 }
1442}
1443
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001444func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1445
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001446 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001447
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001448 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001449 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001450 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1451 pDevEntry.MutexOnuImageStatus.Lock()
1452 pDevEntry.POnuImageStatus = onuImageStatus
1453 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001454
1455 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001456 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001457 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1458 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001459 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1460 pDevEntry.MutexOnuImageStatus.Lock()
1461 pDevEntry.POnuImageStatus = nil
1462 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001463 return images, err
1464}
1465
Himani Chawla6d2ae152020-09-02 13:11:20 +05301466// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001467// #####################################################################################
1468
1469// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301470// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001471
dbainbri4d3a0dc2020-12-02 00:33:42 +00001472func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001473 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 +00001474}
1475
1476// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001477func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001478
dbainbri4d3a0dc2020-12-02 00:33:42 +00001479 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001480 var err error
1481
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001482 // populate what we know. rest comes later after mib sync
1483 dh.device.Root = false
1484 dh.device.Vendor = "OpenONU"
1485 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001486 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
1487 dh.SetDeviceReason(cmn.DrActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001488
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001489 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001490
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001491 if !dh.IsReconciling() {
1492 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001493 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1494 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1495 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301496 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001497 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001498 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001499 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001500 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001501
Himani Chawla4d908332020-08-31 12:30:20 +05301502 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001503 dh.ponPortNumber = dh.device.ParentPortNo
1504
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001505 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1506 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1507 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001508 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001509 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301510 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001511
1512 /*
1513 self._pon = PonPort.create(self, self._pon_port_number)
1514 self._pon.add_peer(self.parent_id, self._pon_port_number)
1515 self.logger.debug('adding-pon-port-to-agent',
1516 type=self._pon.get_port().type,
1517 admin_state=self._pon.get_port().admin_state,
1518 oper_status=self._pon.get_port().oper_status,
1519 )
1520 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001521 if !dh.IsReconciling() {
1522 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001523 var ponPortNo uint32 = 1
1524 if dh.ponPortNumber != 0 {
1525 ponPortNo = dh.ponPortNumber
1526 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001527
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001528 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001529 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001530 PortNo: ponPortNo,
1531 Label: fmt.Sprintf("pon-%d", ponPortNo),
1532 Type: voltha.Port_PON_ONU,
1533 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301534 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001535 PortNo: ponPortNo}}, // Peer port is parent's port number
1536 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001537 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001538 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001539 e.Cancel(err)
1540 return
1541 }
1542 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001543 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001544 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001545 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001546}
1547
1548// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001549func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001550
dbainbri4d3a0dc2020-12-02 00:33:42 +00001551 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001552 var err error
1553 /*
1554 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1555 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1556 return nil
1557 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001558 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1559 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001560 e.Cancel(err)
1561 return
1562 }
1563
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001564 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001565 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001566 // reconcilement will be continued after mib download is done
1567 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001568
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001569 /*
1570 ############################################################################
1571 # Setup Alarm handler
1572 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1573 device.serial_number)
1574 ############################################################################
1575 # Setup PM configuration for this device
1576 # Pass in ONU specific options
1577 kwargs = {
1578 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1579 'heartbeat': self.heartbeat,
1580 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1581 }
1582 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1583 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1584 self.logical_device_id, device.serial_number,
1585 grouped=True, freq_override=False, **kwargs)
1586 pm_config = self._pm_metrics.make_proto()
1587 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1588 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1589 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1590
1591 # Note, ONU ID and UNI intf set in add_uni_port method
1592 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1593 ani_ports=[self._pon])
1594
1595 # Code to Run OMCI Test Action
1596 kwargs_omci_test_action = {
1597 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1598 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1599 }
1600 serial_number = device.serial_number
1601 self._test_request = OmciTestRequest(self.core_proxy,
1602 self.omci_agent, self.device_id,
1603 AniG, serial_number,
1604 self.logical_device_id,
1605 exclusive=False,
1606 **kwargs_omci_test_action)
1607
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001608 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001609 else:
1610 self.logger.info('onu-already-activated')
1611 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001612
dbainbri4d3a0dc2020-12-02 00:33:42 +00001613 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001614}
1615
1616// doStateConnected get the device info and update to voltha core
1617// for comparison of the original method (not that easy to uncomment): compare here:
1618// voltha-openolt-adapter/adaptercore/device_handler.go
1619// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001620func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001621
dbainbri4d3a0dc2020-12-02 00:33:42 +00001622 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301623 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001624 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001625 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001626}
1627
1628// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001629func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001630
dbainbri4d3a0dc2020-12-02 00:33:42 +00001631 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301632 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001633 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001634 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001635
1636 /*
1637 // Synchronous call to update device state - this method is run in its own go routine
1638 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1639 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001640 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 +00001641 return err
1642 }
1643 return nil
1644 */
1645}
1646
1647// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001648func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001649
dbainbri4d3a0dc2020-12-02 00:33:42 +00001650 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001651 var err error
1652
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001653 device := dh.device
1654 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001655 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001656 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001657 e.Cancel(err)
1658 return
1659 }
1660
1661 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001662 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001663 /*
1664 // Update the all ports state on that device to disable
1665 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001666 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001667 return er
1668 }
1669
1670 //Update the device oper state and connection status
1671 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1672 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1673 dh.device = cloned
1674
1675 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001676 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001677 return er
1678 }
1679
1680 //get the child device for the parent device
1681 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1682 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001683 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001684 return err
1685 }
1686 for _, onuDevice := range onuDevices.Items {
1687
1688 // Update onu state as down in onu adapter
1689 onuInd := oop.OnuIndication{}
1690 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001691 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001692 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1693 if er != nil {
1694 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001695 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001696 //Do not return here and continue to process other ONUs
1697 }
1698 }
1699 // * Discovered ONUs entries need to be cleared , since after OLT
1700 // is up, it starts sending discovery indications again* /
1701 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001702 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001703 return nil
1704 */
Himani Chawla4d908332020-08-31 12:30:20 +05301705 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001706 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001707 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001708}
1709
Himani Chawla6d2ae152020-09-02 13:11:20 +05301710// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001711// #################################################################################
1712
1713// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301714// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001715
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001716//GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
1717func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001718 dh.lockDevice.RLock()
1719 pOnuDeviceEntry := dh.pOnuOmciDevice
1720 if aWait && pOnuDeviceEntry == nil {
1721 //keep the read sema short to allow for subsequent write
1722 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001723 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001724 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1725 // so it might be needed to wait here for that event with some timeout
1726 select {
1727 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001728 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001729 return nil
1730 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001731 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001732 // if written now, we can return the written value without sema
1733 return dh.pOnuOmciDevice
1734 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001735 }
mpagenko3af1f032020-06-10 08:53:41 +00001736 dh.lockDevice.RUnlock()
1737 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001738}
1739
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001740//setDeviceHandlerEntries sets the ONU device entry within the handler
1741func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1742 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001743 dh.lockDevice.Lock()
1744 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001745 dh.pOnuOmciDevice = apDeviceEntry
1746 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001747 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301748 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001749 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001750}
1751
Himani Chawla6d2ae152020-09-02 13:11:20 +05301752//addOnuDeviceEntry creates a new ONU device or returns the existing
1753func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001754 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001755
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001756 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001757 if deviceEntry == nil {
1758 /* costum_me_map in python code seems always to be None,
1759 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1760 /* also no 'clock' argument - usage open ...*/
1761 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001762 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1763 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1764 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1765 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1766 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001767 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001768 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001769 // fire deviceEntry ready event to spread to possibly waiting processing
1770 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001771 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001772 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001773 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001774 }
1775 // might be updated with some error handling !!!
1776 return nil
1777}
1778
dbainbri4d3a0dc2020-12-02 00:33:42 +00001779func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1780 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001781 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1782
1783 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001784
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001785 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001786 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001787 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1788 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001789 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001790 if !dh.IsReconciling() {
1791 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001792 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001793 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001794 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001795 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001796 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001797
khenaidoo42dcdfd2021-10-19 17:34:12 -04001798 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001799 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001800 OperStatus: voltha.OperStatus_ACTIVATING,
1801 ConnStatus: voltha.ConnectStatus_REACHABLE,
1802 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001803 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001804 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001805 }
1806 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001807 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001808 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001809
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001810 pDevEntry.MutexPersOnuConfig.RLock()
1811 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1812 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001813 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 +00001814 log.Fields{"device-id": dh.DeviceID})
1815 dh.StopReconciling(ctx, true)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001816 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001817 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001818 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001819 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001820 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1821 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1822 // 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 +00001823 // 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 +00001824 // so let's just try to keep it simple ...
1825 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001826 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001827 if err != nil || device == nil {
1828 //TODO: needs to handle error scenarios
1829 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1830 return errors.New("Voltha Device not found")
1831 }
1832 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001833
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001834 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001835 return err
mpagenko3af1f032020-06-10 08:53:41 +00001836 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001837
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001838 _ = dh.deviceReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001839
1840 /* this might be a good time for Omci Verify message? */
1841 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001842 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001843 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001844 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001845 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001846
1847 /* give the handler some time here to wait for the OMCi verification result
1848 after Timeout start and try MibUpload FSM anyway
1849 (to prevent stopping on just not supported OMCI verification from ONU) */
1850 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001851 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001852 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001853 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001854 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001855 }
1856
1857 /* In py code it looks earlier (on activate ..)
1858 # Code to Run OMCI Test Action
1859 kwargs_omci_test_action = {
1860 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1861 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1862 }
1863 serial_number = device.serial_number
1864 self._test_request = OmciTestRequest(self.core_proxy,
1865 self.omci_agent, self.device_id,
1866 AniG, serial_number,
1867 self.logical_device_id,
1868 exclusive=False,
1869 **kwargs_omci_test_action)
1870 ...
1871 # Start test requests after a brief pause
1872 if not self._test_request_started:
1873 self._test_request_started = True
1874 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1875 reactor.callLater(tststart, self._test_request.start_collector)
1876
1877 */
1878 /* which is then: in omci_test_request.py : */
1879 /*
1880 def start_collector(self, callback=None):
1881 """
1882 Start the collection loop for an adapter if the frequency > 0
1883
1884 :param callback: (callable) Function to call to collect PM data
1885 """
1886 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1887 if callback is None:
1888 callback = self.perform_test_omci
1889
1890 if self.lc is None:
1891 self.lc = LoopingCall(callback)
1892
1893 if self.default_freq > 0:
1894 self.lc.start(interval=self.default_freq / 10)
1895
1896 def perform_test_omci(self):
1897 """
1898 Perform the initial test request
1899 """
1900 ani_g_entities = self._device.configuration.ani_g_entities
1901 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1902 is not None else None
1903 self._entity_id = ani_g_entities_ids[0]
1904 self.logger.info('perform-test', entity_class=self._entity_class,
1905 entity_id=self._entity_id)
1906 try:
1907 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1908 result = yield self._device.omci_cc.send(frame)
1909 if not result.fields['omci_message'].fields['success_code']:
1910 self.logger.info('Self-Test Submitted Successfully',
1911 code=result.fields[
1912 'omci_message'].fields['success_code'])
1913 else:
1914 raise TestFailure('Test Failure: {}'.format(
1915 result.fields['omci_message'].fields['success_code']))
1916 except TimeoutError as e:
1917 self.deferred.errback(failure.Failure(e))
1918
1919 except Exception as e:
1920 self.logger.exception('perform-test-Error', e=e,
1921 class_id=self._entity_class,
1922 entity_id=self._entity_id)
1923 self.deferred.errback(failure.Failure(e))
1924
1925 */
1926
1927 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001928 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001929
mpagenko1cc3cb42020-07-27 15:24:38 +00001930 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1931 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1932 * 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 +05301933 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001934 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001935 //call MibUploadFSM - transition up to state UlStInSync
1936 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001937 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001938 if pMibUlFsm.Is(mib.UlStDisabled) {
1939 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
1940 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
1941 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301942 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301944 //Determine ONU status and start/re-start MIB Synchronization tasks
1945 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001946 if pDevEntry.IsNewOnu() {
1947 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
1948 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
1949 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001950 }
Himani Chawla4d908332020-08-31 12:30:20 +05301951 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001952 if err := pMibUlFsm.Event(mib.UlEvExamineMds); err != nil {
1953 logger.Errorw(ctx, "MibSyncFsm: Can't go to state examine_mds", log.Fields{"device-id": dh.DeviceID, "err": err})
1954 return fmt.Errorf("can't go to examine_mds: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301955 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001956 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001957 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001958 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001960 "device-id": dh.DeviceID})
1961 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001962 }
1963 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001964 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
1965 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001966 }
1967 return nil
1968}
1969
dbainbri4d3a0dc2020-12-02 00:33:42 +00001970func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001971 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001972 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001973 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
1974 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001975
mpagenko900ee4b2020-10-12 11:56:34 +00001976 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1977 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1978 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001979 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001980 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001981 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001982 // abort: system behavior is just unstable ...
1983 return err
1984 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001985 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001986 _ = 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 +00001987
1988 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1989 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1990 //stop the device entry which resets the attached omciCC
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001991 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001992 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001993 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
1994 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001995 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001996 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001997
1998 //TODO!!! remove existing traffic profiles
1999 /* from py code, if TP's exist, remove them - not yet implemented
2000 self._tp = dict()
2001 # Let TP download happen again
2002 for uni_id in self._tp_service_specific_task:
2003 self._tp_service_specific_task[uni_id].clear()
2004 for uni_id in self._tech_profile_download_done:
2005 self._tech_profile_download_done[uni_id].clear()
2006 */
2007
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002008 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002009
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002010 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002011
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002012 if err := dh.deviceReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002013 // abort: system behavior is just unstable ...
2014 return err
2015 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002016 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002017 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002018 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002019 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002020 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2021 OperStatus: voltha.OperStatus_DISCOVERED,
2022 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002023 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002024 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002025 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002026 // abort: system behavior is just unstable ...
2027 return err
2028 }
2029 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002030 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002031 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002032 return nil
2033}
2034
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002035func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002036 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2037 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2038 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2039 // and using the stop/reset event should never harm
2040
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002041 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002042 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002043 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2044 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00002045 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002046 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002047 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002048 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002049 pDevEntry.MutexOnuImageStatus.RLock()
2050 if pDevEntry.POnuImageStatus != nil {
2051 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002052 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002053 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002054
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002055 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002056 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002057 }
2058 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002059 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002060 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002061 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002062 }
2063 //port lock/unlock FSM's may be active
2064 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002065 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002066 }
2067 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002068 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002069 }
2070 //techProfile related PonAniConfigFsm FSM may be active
2071 if dh.pOnuTP != nil {
2072 // should always be the case here
2073 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002074 if dh.pOnuTP.PAniConfigFsm != nil {
2075 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2076 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002077 }
mpagenko900ee4b2020-10-12 11:56:34 +00002078 }
2079 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002080 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002081 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002082 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002083 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002084 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002085 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002086 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002087 } else {
2088 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002089 }
2090 }
2091 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002092 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002093 // Stop collector routine
2094 dh.stopCollector <- true
2095 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002096 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302097 dh.stopAlarmManager <- true
2098 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002099 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002100 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002101 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302102
Girish Gowdrae95687a2021-09-08 16:30:58 -07002103 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2104
mpagenko80622a52021-02-09 16:53:23 +00002105 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002106 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002107 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002108 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002109 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002110 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002111 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002112 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2113 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2114 // (even though it may also run into direct cancellation, a bit hard to verify here)
2115 // so don't set 'dh.upgradeCanceled = true' here!
2116 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2117 }
mpagenko38662d02021-08-11 09:45:19 +00002118 }
mpagenko80622a52021-02-09 16:53:23 +00002119
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002120 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002121 return nil
2122}
2123
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002124func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2125 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 +05302126
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002127 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002128 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002129 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002130 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002131 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002132 _ = dh.deviceReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling())
2133 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002134
mpagenkoa40e99a2020-11-17 13:50:39 +00002135 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2136 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2137 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2138 * disable/enable toggling here to allow traffic
2139 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2140 * like the py comment says:
2141 * # start by locking all the unis till mib sync and initial mib is downloaded
2142 * # this way we can capture the port down/up events when we are ready
2143 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302144
mpagenkoa40e99a2020-11-17 13:50:39 +00002145 // Init Uni Ports to Admin locked state
2146 // *** should generate UniLockStateDone event *****
2147 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002148 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002149 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002150 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002151 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002152 }
2153}
2154
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002155func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2156 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302157 /* Mib download procedure -
2158 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2159 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002160 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002161 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002162 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002163 return
2164 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002165 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302166 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002167 if pMibDlFsm.Is(mib.DlStDisabled) {
2168 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2169 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 +05302170 // maybe try a FSM reset and then again ... - TODO!!!
2171 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002172 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302173 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002174 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2175 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302176 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002177 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302178 //Begin MIB data download (running autonomously)
2179 }
2180 }
2181 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002182 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002183 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302184 // maybe try a FSM reset and then again ... - TODO!!!
2185 }
2186 /***** Mib download started */
2187 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002188 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302189 }
2190}
2191
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002192func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2193 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302194 //initiate DevStateUpdate
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002195 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002196 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002197 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002198 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2199 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2200 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2201 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002202 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002203 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002204 ConnStatus: voltha.ConnectStatus_REACHABLE,
2205 OperStatus: voltha.OperStatus_ACTIVE,
2206 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302207 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002208 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302209 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002210 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302211 }
2212 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002213 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002214 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302215 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002216 _ = dh.deviceReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002217
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002218 if !dh.GetCollectorIsRunning() {
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002219 // Start PM collector routine
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002220 go dh.StartCollector(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002221 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002222 if !dh.GetAlarmManagerIsRunning(ctx) {
2223 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002224 }
2225
Girish Gowdrae95687a2021-09-08 16:30:58 -07002226 // Start flow handler routines per UNI
2227 for _, uniPort := range dh.uniEntityMap {
2228 // only if this port was enabled for use by the operator at startup
2229 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2230 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2231 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2232 }
2233 }
2234 }
2235
Girish Gowdrae0140f02021-02-02 16:55:09 -08002236 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002237 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002238 // There is no way we should be landing here, but if we do then
2239 // there is nothing much we can do about this other than log error
2240 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2241 }
2242
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002243 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002244
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002245 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002246 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002247 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002248 return
2249 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002250 pDevEntry.MutexPersOnuConfig.RLock()
2251 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2252 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002253 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002254 log.Fields{"device-id": dh.DeviceID})
2255 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002256 // reconcilement will be continued after ani config is done
2257 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002258 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002259 // *** should generate UniUnlockStateDone event *****
2260 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002261 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002262 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002263 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002264 dh.runUniLockFsm(ctx, false)
2265 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302266 }
2267}
2268
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002269func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2270 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302271
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002272 if !dh.IsReconciling() {
2273 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002274 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002275 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2276 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002277 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002278 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002279 return
2280 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002281 pDevEntry.MutexPersOnuConfig.Lock()
2282 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2283 pDevEntry.MutexPersOnuConfig.Unlock()
2284 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002285 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002286 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002287 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302288 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002289 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 +00002290 log.Fields{"device-id": dh.DeviceID})
2291 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002292 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302293 }
2294}
2295
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002296func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002297 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002298 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002299
khenaidoo42dcdfd2021-10-19 17:34:12 -04002300 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002301 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002302 ConnStatus: voltha.ConnectStatus_REACHABLE,
2303 OperStatus: voltha.OperStatus_UNKNOWN,
2304 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002305 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002306 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002307 }
2308
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002309 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002310 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002311 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002312
2313 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002314 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002315
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002316 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002317 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002318 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002319 return
2320 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002321 pDevEntry.MutexPersOnuConfig.Lock()
2322 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2323 pDevEntry.MutexPersOnuConfig.Unlock()
2324 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002325 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002326 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002327 }
mpagenko900ee4b2020-10-12 11:56:34 +00002328}
2329
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002330func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002331 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002332 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002333 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002334 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002335 ConnStatus: voltha.ConnectStatus_REACHABLE,
2336 OperStatus: voltha.OperStatus_ACTIVE,
2337 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002338 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002339 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002340 }
2341
dbainbri4d3a0dc2020-12-02 00:33:42 +00002342 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002343 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002344 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002345 _ = dh.deviceReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002346
2347 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002348 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002349
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002350 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002351 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002352 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002353 return
2354 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002355 pDevEntry.MutexPersOnuConfig.Lock()
2356 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2357 pDevEntry.MutexPersOnuConfig.Unlock()
2358 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002359 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002360 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002361 }
mpagenko900ee4b2020-10-12 11:56:34 +00002362}
2363
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002364func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2365 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2366 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002367 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002368 DeviceId: dh.DeviceID,
2369 OperStatus: voltha.OperStatus_FAILED,
2370 }); err != nil {
2371 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2372 }
2373}
2374
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002375func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2376 if devEvent == cmn.OmciAniConfigDone {
2377 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002378 // attention: the device reason update is done based on ONU-UNI-Port related activity
2379 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002380 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002381 // 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 +00002382 _ = dh.deviceReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302383 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002384 if dh.IsReconciling() {
2385 go dh.ReconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002386 }
2387 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002388 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002389 // attention: the device reason update is done based on ONU-UNI-Port related activity
2390 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002391 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002392 // 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 +00002393 _ = dh.deviceReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002394 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002395 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302396}
2397
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002398func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002399 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002400 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302401 // attention: the device reason update is done based on ONU-UNI-Port related activity
2402 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302403
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002404 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2405 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002406 // which may be the case from some previous actvity on another UNI Port of the ONU
2407 // or even some previous flow add activity on the same port
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002408 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling())
2409 if dh.IsReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002410 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002411 }
2412 }
2413 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002414 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002415 //not relevant for reconcile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002416 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002417 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302418 }
mpagenkof1fc3862021-02-16 10:09:52 +00002419
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002420 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002421 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002422 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002423 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002424 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002425 }
2426 } else {
2427 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002428 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002429 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302430}
2431
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002432//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
2433func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302434 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002435 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002436 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002437 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002438 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002439 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002440 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002441 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002442 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002443 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002444 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002445 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002446 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002447 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002448 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002449 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002450 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002451 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002452 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002453 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002454 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002455 case cmn.UniEnableStateFailed:
2456 {
2457 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2458 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002459 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002460 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002461 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002462 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002463 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002464 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002465 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002466 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002467 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002468 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002469 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002470 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002471 default:
2472 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002473 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002474 }
2475 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002476}
2477
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002478func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002479 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002480 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302481 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002482 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002483 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002484 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302485 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002486 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002487 if pUniPort == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002488 logger.Warnw(ctx, "OnuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002489 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002490 //store UniPort with the System-PortNumber key
2491 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002492 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002493 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002494 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
2495 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002496 } //error logging already within UniPort method
2497 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002498 logger.Debugw(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002499 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002500 }
2501 }
2502}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002503
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002504func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2505 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002506 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002507 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002508 return
2509 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002510 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002511 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002512 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2513 for _, mgmtEntityID := range pptpInstKeys {
2514 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002515 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002516 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2517 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002518 }
2519 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002520 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002521 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002522 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002523 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2524 for _, mgmtEntityID := range veipInstKeys {
2525 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002526 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002527 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2528 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002529 }
2530 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002531 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002532 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002533 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002534 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2535 for _, mgmtEntityID := range potsInstKeys {
2536 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002537 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002538 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2539 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002540 }
2541 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002542 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002543 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002544 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002545 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002546 return
2547 }
2548
2549 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2550 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2551 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
2552 for i := 0; i < int(uniCnt); i++ {
2553 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
2554 dh.stopFlowMonitoringRoutine[i] = make(chan bool)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002555 }
2556}
2557
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002558// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2559func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002560 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302561 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002562 // with following remark:
2563 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2564 // # load on the core
2565
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002566 // 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 +00002567
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002568 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002569 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002570 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2571 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2572 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2573 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002574 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002575 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002576 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002577 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002578 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002579 PortNo: port.PortNo,
2580 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002581 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002582 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 -04002583 }
2584 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002585 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002586 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002587 }
mpagenko3af1f032020-06-10 08:53:41 +00002588 }
2589 }
2590}
2591
2592// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002593func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2594 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002595 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2596 for uniNo, uniPort := range dh.uniEntityMap {
2597 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002598
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002599 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2600 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2601 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2602 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002603 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002604 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002605 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002606 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002607 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002608 PortNo: port.PortNo,
2609 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002610 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002611 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 -04002612 }
2613 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002614 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002615 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002616 }
2617
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002618 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002619 }
2620}
2621
2622// ONU_Active/Inactive announcement on system KAFKA bus
2623// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002624func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002625 var de voltha.DeviceEvent
2626 eventContext := make(map[string]string)
2627 //Populating event context
2628 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002629 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002630 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002631 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302632 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002633 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 +00002634 }
2635 oltSerialNumber := parentDevice.SerialNumber
2636
2637 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2638 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2639 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302640 eventContext["olt-serial-number"] = oltSerialNumber
2641 eventContext["device-id"] = aDeviceID
2642 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002643 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002644 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2645 deviceEntry.MutexPersOnuConfig.RLock()
2646 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2647 deviceEntry.MutexPersOnuConfig.RUnlock()
2648 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
2649 deviceEntry.MutexPersOnuConfig.RLock()
2650 eventContext["vendor"] = deviceEntry.SOnuPersistentData.PersVendorID
2651 deviceEntry.MutexPersOnuConfig.RUnlock()
2652 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002653 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2654 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2655 } else {
2656 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2657 log.Fields{"device-id": aDeviceID})
2658 return
2659 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002660
2661 /* Populating device event body */
2662 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302663 de.ResourceId = aDeviceID
2664 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002665 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2666 de.Description = fmt.Sprintf("%s Event - %s - %s",
2667 cEventObjectType, cOnuActivatedEvent, "Raised")
2668 } else {
2669 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2670 de.Description = fmt.Sprintf("%s Event - %s - %s",
2671 cEventObjectType, cOnuActivatedEvent, "Cleared")
2672 }
2673 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002674 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2675 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302676 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002677 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002678 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302679 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002680}
2681
Himani Chawla4d908332020-08-31 12:30:20 +05302682// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002683func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2684 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002685 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302686 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002687 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002688 sFsmName = "LockStateFSM"
2689 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002690 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002691 sFsmName = "UnLockStateFSM"
2692 }
mpagenko3af1f032020-06-10 08:53:41 +00002693
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002694 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002695 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002696 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002697 return
2698 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002699 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002700 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302701 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002702 dh.pLockStateFsm = pLSFsm
2703 } else {
2704 dh.pUnlockStateFsm = pLSFsm
2705 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002706 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002707 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002708 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002709 }
2710}
2711
2712// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002713func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002714 /* Uni Port lock/unlock procedure -
2715 ***** should run via 'adminDone' state and generate the argument requested event *****
2716 */
2717 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302718 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002719 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002720 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2721 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002722 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2723 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002724 }
2725 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002726 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002727 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2728 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002729 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2730 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002731 }
2732 }
2733 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002734 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2735 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002736 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002737 // maybe try a FSM reset and then again ... - TODO!!!
2738 } else {
2739 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002740 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002741 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002742 }
2743 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002744 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002745 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002746 // maybe try a FSM reset and then again ... - TODO!!!
2747 }
2748 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002749 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002750 // maybe try a FSM reset and then again ... - TODO!!!
2751 }
2752}
2753
mpagenko80622a52021-02-09 16:53:23 +00002754// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00002755// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002756func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002757 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002758 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002759 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002760 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002761 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002762 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002763 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002764 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002765 sFsmName, chUpgradeFsm)
2766 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002767 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00002768 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002769 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
2770 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
mpagenko80622a52021-02-09 16:53:23 +00002771 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2772 // maybe try a FSM reset and then again ... - TODO!!!
2773 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2774 }
mpagenko59862f02021-10-11 08:53:18 +00002775 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00002776 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2777 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00002778 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2779 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002780 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002781 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002782 } else {
2783 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002784 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002785 // maybe try a FSM reset and then again ... - TODO!!!
2786 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2787 }
2788 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002789 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002790 // maybe try a FSM reset and then again ... - TODO!!!
2791 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2792 }
2793 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002794 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002795 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2796 }
2797 return nil
2798}
2799
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002800// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
2801func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002802 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002803 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002804 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00002805 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2806 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00002807 dh.pLastUpgradeImageState = apImageState
2808 dh.lockUpgradeFsm.Unlock()
2809 //signal upgradeFsm removed using non-blocking channel send
2810 select {
2811 case dh.upgradeFsmChan <- struct{}{}:
2812 default:
2813 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002814 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00002815 }
mpagenko80622a52021-02-09 16:53:23 +00002816}
2817
mpagenko15ff4a52021-03-02 10:09:20 +00002818// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2819func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002820 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00002821 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002822 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002823 return
2824 }
2825
2826 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00002827 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00002828 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002829 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
2830 dh.lockUpgradeFsm.RUnlock()
2831 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
2832 return
2833 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002834 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00002835 if pUpgradeStatemachine != nil {
2836 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2837 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002838 UpgradeState := pUpgradeStatemachine.Current()
2839 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
2840 (UpgradeState == swupg.UpgradeStRequestingActivate) {
2841 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00002842 // 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 +00002843 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00002844 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
2845 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00002846 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00002847 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002848 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00002849 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2850 dh.upgradeCanceled = true
2851 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2852 }
mpagenko15ff4a52021-03-02 10:09:20 +00002853 return
2854 }
mpagenko59862f02021-10-11 08:53:18 +00002855 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002856 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
2857 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00002858 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002859 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
mpagenko1f8e8822021-06-25 14:10:21 +00002860 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
2861 return
2862 }
2863 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002864 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00002865 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002866 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
2867 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
mpagenko1f8e8822021-06-25 14:10:21 +00002868 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2869 return
2870 }
2871 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002872 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00002873 }
2874 } else {
2875 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 +00002876 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00002877 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2878 dh.upgradeCanceled = true
2879 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2880 }
mpagenko1f8e8822021-06-25 14:10:21 +00002881 }
mpagenko15ff4a52021-03-02 10:09:20 +00002882 return
2883 }
mpagenko59862f02021-10-11 08:53:18 +00002884 dh.lockUpgradeFsm.RUnlock()
2885 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2886 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00002887 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2888 dh.upgradeCanceled = true
2889 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2890 }
mpagenko59862f02021-10-11 08:53:18 +00002891 return
2892 }
2893 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2894 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2895 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2896 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
2897 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2898 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
2899 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00002900 }
mpagenko15ff4a52021-03-02 10:09:20 +00002901 }
2902 }
2903 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002904 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002905 }
mpagenko59862f02021-10-11 08:53:18 +00002906 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00002907}
2908
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002909//SetBackend provides a DB backend for the specified path on the existing KV client
2910func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002911
2912 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002913 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07002914 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00002915 kvbackend := &db.Backend{
2916 Client: dh.pOpenOnuAc.kvClient,
2917 StoreType: dh.pOpenOnuAc.KVStoreType,
2918 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002919 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002920 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2921 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002922
mpagenkoaf801632020-07-03 10:00:42 +00002923 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002924}
khenaidoo7d3c5582021-08-11 18:09:44 -04002925func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302926 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002927
mpagenkodff5dda2020-08-28 11:52:01 +00002928 for _, field := range flow.GetOfbFields(apFlowItem) {
2929 switch field.Type {
2930 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2931 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002932 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002933 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2934 }
mpagenko01e726e2020-10-23 09:45:29 +00002935 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002936 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2937 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302938 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002939 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302940 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2941 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002942 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2943 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002944 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002945 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302946 return
mpagenkodff5dda2020-08-28 11:52:01 +00002947 }
2948 }
mpagenko01e726e2020-10-23 09:45:29 +00002949 */
mpagenkodff5dda2020-08-28 11:52:01 +00002950 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2951 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302952 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002953 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302954 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002955 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302956 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002957 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002958 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302959 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002960 }
2961 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2962 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302963 *loAddPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002964 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002965 "PCP": loAddPcp})
2966 }
2967 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2968 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002969 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002970 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2971 }
2972 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2973 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002974 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002975 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2976 }
2977 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2978 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002979 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002980 "IPv4-DST": field.GetIpv4Dst()})
2981 }
2982 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2983 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002984 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002985 "IPv4-SRC": field.GetIpv4Src()})
2986 }
2987 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2988 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002989 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002990 "Metadata": field.GetTableMetadata()})
2991 }
2992 /*
2993 default:
2994 {
2995 //all other entires ignored
2996 }
2997 */
2998 }
2999 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303000}
mpagenkodff5dda2020-08-28 11:52:01 +00003001
khenaidoo7d3c5582021-08-11 18:09:44 -04003002func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003003 for _, action := range flow.GetActions(apFlowItem) {
3004 switch action.Type {
3005 /* not used:
3006 case of.OfpActionType_OFPAT_OUTPUT:
3007 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003008 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003009 "Output": action.GetOutput()})
3010 }
3011 */
3012 case of.OfpActionType_OFPAT_PUSH_VLAN:
3013 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003014 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003015 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3016 }
3017 case of.OfpActionType_OFPAT_SET_FIELD:
3018 {
3019 pActionSetField := action.GetSetField()
3020 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003021 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003022 "OxcmClass": pActionSetField.Field.OxmClass})
3023 }
3024 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303025 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003026 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303027 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003028 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303029 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003030 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303031 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003032 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003033 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003034 "Type": pActionSetField.Field.GetOfbField().Type})
3035 }
3036 }
3037 /*
3038 default:
3039 {
3040 //all other entires ignored
3041 }
3042 */
3043 }
3044 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303045}
3046
3047//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003048func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003049 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303050 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3051 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
3052 var loAddPcp, loSetPcp uint8
3053 var loIPProto uint32
3054 /* the TechProfileId is part of the flow Metadata - compare also comment within
3055 * OLT-Adapter:openolt_flowmgr.go
3056 * Metadata 8 bytes:
3057 * Most Significant 2 Bytes = Inner VLAN
3058 * Next 2 Bytes = Tech Profile ID(TPID)
3059 * Least Significant 4 Bytes = Port ID
3060 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3061 * subscriber related flows.
3062 */
3063
dbainbri4d3a0dc2020-12-02 00:33:42 +00003064 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303065 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003066 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003067 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003068 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303069 }
mpagenko551a4d42020-12-08 18:09:20 +00003070 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003071 loCookie := apFlowItem.GetCookie()
3072 loCookieSlice := []uint64{loCookie}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003073 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003074 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05303075
dbainbri4d3a0dc2020-12-02 00:33:42 +00003076 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003077 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303078 if loIPProto == 2 {
3079 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3080 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003081 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003082 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303083 return nil
3084 }
mpagenko01e726e2020-10-23 09:45:29 +00003085 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003086 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003087
3088 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003089 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003090 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003091 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3092 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3093 //TODO!!: Use DeviceId within the error response to rwCore
3094 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003095 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003096 }
3097 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003098 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003099 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3100 } else {
3101 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3102 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3103 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303104 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003105 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003106 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003107 }
mpagenko9a304ea2020-12-16 15:54:01 +00003108
khenaidoo42dcdfd2021-10-19 17:34:12 -04003109 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003110 if apFlowMetaData != nil {
3111 meter = apFlowMetaData.Meters[0]
3112 }
mpagenkobc4170a2021-08-17 16:42:10 +00003113 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3114 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3115 // when different rules are requested concurrently for the same uni
3116 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3117 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3118 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003119 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3120 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003121 //SetUniFlowParams() may block on some rule that is suspended-to-add
3122 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003123 // Also the error is returned to caller via response channel
3124 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
3125 loMatchVlan, loSetVlan, loSetPcp, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003126 dh.lockVlanConfig.RUnlock()
3127 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003128 return
mpagenkodff5dda2020-08-28 11:52:01 +00003129 }
mpagenkobc4170a2021-08-17 16:42:10 +00003130 dh.lockVlanConfig.RUnlock()
3131 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003132 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003133 loMatchVlan, loSetVlan, loSetPcp, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003134 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003135 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003136 if err != nil {
3137 *respChan <- err
3138 }
mpagenko01e726e2020-10-23 09:45:29 +00003139}
3140
3141//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003142func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003143 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3144 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3145 //no extra check is done on the rule parameters
3146 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3147 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3148 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3149 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003150 // - 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 +00003151 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003152 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003153
3154 /* TT related temporary workaround - should not be needed anymore
3155 for _, field := range flow.GetOfbFields(apFlowItem) {
3156 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3157 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003158 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003159 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3160 if loIPProto == 2 {
3161 // 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 +00003162 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003163 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003164 return nil
3165 }
3166 }
3167 } //for all OfbFields
3168 */
3169
mpagenko9a304ea2020-12-16 15:54:01 +00003170 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003171 dh.lockVlanConfig.RLock()
3172 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003173 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3174 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003175 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3176 return
mpagenko01e726e2020-10-23 09:45:29 +00003177 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003178 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003179 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003180 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003181 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003182 // Push response on the response channel
3183 if respChan != nil {
3184 // 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
3185 select {
3186 case *respChan <- nil:
3187 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3188 default:
3189 }
3190 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003191 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003192}
3193
Himani Chawla26e555c2020-08-31 12:30:20 +05303194// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003195// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003196// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003197func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003198 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent cmn.OnuDeviceEvent, lastFlowToReconcile bool, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003199 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003200
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003201 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003202 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003203 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3204 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003205 }
3206
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003207 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3208 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003209 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003210 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003211 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3212 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003213 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3214 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003215 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003216 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3217 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003218 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003219 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003220 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303221 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003222 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003223 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3224 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003225 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003226 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003227 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3228 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003229 }
3230 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003231 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003232 "device-id": dh.DeviceID})
3233 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003234 }
3235 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003236 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003237 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3238 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003239 }
3240 return nil
3241}
3242
mpagenkofc4f56e2020-11-04 17:17:49 +00003243//VerifyVlanConfigRequest checks on existence of a given uniPort
3244// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003245func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003246 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003247 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003248 for _, uniPort := range dh.uniEntityMap {
3249 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003250 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003251 pCurrentUniPort = uniPort
3252 break //found - end search loop
3253 }
3254 }
3255 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003256 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003257 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003258 return
3259 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003260 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003261}
3262
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003263//VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
3264func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003265 //TODO!! verify and start pending flow configuration
3266 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3267 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003268
3269 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003270 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003271 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003272 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003273 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003274 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003275 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003276 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003277 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3278 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003279 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003280 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003281 } else {
3282 /***** UniVlanConfigFsm continued */
3283 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003284 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3285 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003286 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003287 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3288 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003289 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003290 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003291 } else {
3292 /***** UniVlanConfigFsm continued */
3293 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003294 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3295 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003296 }
mpagenkodff5dda2020-08-28 11:52:01 +00003297 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003298 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003299 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3300 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003301 }
3302 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003303 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 +00003304 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3305 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003306 }
3307 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003308 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003309 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003310 }
mpagenkof1fc3862021-02-16 10:09:52 +00003311 } else {
3312 dh.lockVlanConfig.RUnlock()
3313 }
mpagenkodff5dda2020-08-28 11:52:01 +00003314}
3315
3316//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3317// 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 +00003318func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003319 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003320 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003321 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003322 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003323 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003324 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003325}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003326
mpagenkof1fc3862021-02-16 10:09:52 +00003327//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003328func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003329 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3330 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3331 // obviously then parallel processing on the cancel must be avoided
3332 // deadline context to ensure completion of background routines waited for
3333 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3334 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3335 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3336
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003337 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003338 var wg sync.WaitGroup
3339 wg.Add(1) // for the 1 go routine to finish
3340
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003341 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003342 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3343
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003344 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003345}
3346
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003347//StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003348//available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003349func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3350 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003351
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003352 if dh.IsReconciling() {
3353 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003354 return nil
3355 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003356 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003357
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003358 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003359 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003360 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3361 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003362 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003363 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003364
mpagenkof1fc3862021-02-16 10:09:52 +00003365 if aWriteToKvStore {
3366 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3367 }
3368 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003369}
3370
dbainbri4d3a0dc2020-12-02 00:33:42 +00003371func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003372 defer cancel() //ensure termination of context (may be pro forma)
3373 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003374 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003375 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003376}
3377
dbainbri4d3a0dc2020-12-02 00:33:42 +00003378func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003379
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003380 dh.SetDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003381 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003382 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003383 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003384 DeviceId: dh.DeviceID,
3385 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003386 }); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003387 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003388 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003389 return err
3390 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003391 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", cmn.DeviceReasonMap[deviceReason], dh.DeviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003392 return nil
3393 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003394 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 +00003395 return nil
3396}
3397
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003398func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3399 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003400 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003401 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3402 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003403 }
mpagenkof1fc3862021-02-16 10:09:52 +00003404 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003405}
3406
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003407// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003408// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003409func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3410 dh.lockDevice.RLock()
3411 defer dh.lockDevice.RUnlock()
3412 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003413 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003414 }
3415 return 0, errors.New("error-fetching-uni-port")
3416}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003417
3418// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003419func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3420 var errorsList []error
3421 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 -08003422
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003423 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3424 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3425 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3426
3427 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3428 // successfully.
3429 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3430 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3431 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003432 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 -08003433 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003434 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003435 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003436 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003437}
3438
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003439func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3440 var err error
3441 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003442 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003443
3444 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003445 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003446 errorsList = append(errorsList, err)
3447 }
3448 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003449 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003450
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003451 return errorsList
3452}
3453
3454func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3455 var err error
3456 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003457 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003458 // Check if group metric related config is updated
3459 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003460 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3461 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3462 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003463
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003464 if ok && m.Frequency != v.GroupFreq {
3465 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003466 errorsList = append(errorsList, err)
3467 }
3468 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003469 if ok && m.Enabled != v.Enabled {
3470 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003471 errorsList = append(errorsList, err)
3472 }
3473 }
3474 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003475 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003476 return errorsList
3477}
3478
3479func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3480 var err error
3481 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003482 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003483 // Check if standalone metric related config is updated
3484 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003485 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3486 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3487 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003488
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003489 if ok && m.Frequency != v.SampleFreq {
3490 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003491 errorsList = append(errorsList, err)
3492 }
3493 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003494 if ok && m.Enabled != v.Enabled {
3495 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003496 errorsList = append(errorsList, err)
3497 }
3498 }
3499 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003500 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003501 return errorsList
3502}
3503
3504// nolint: gocyclo
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003505func (dh *deviceHandler) StartCollector(ctx context.Context) {
Girish Gowdrae09a6202021-01-12 18:10:59 -08003506 logger.Debugf(ctx, "startingCollector")
3507
3508 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003509 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303510 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003511 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003512 // Initialize the next metric collection time.
3513 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3514 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003515 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003516 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003517 for {
3518 select {
3519 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003520 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003521 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003522 // Stop the L2 PM FSM
3523 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003524 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3525 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3526 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003527 }
3528 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003529 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003530 }
3531 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003532 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3533 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003534 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003535 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3536 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003537 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003538
Girish Gowdrae09a6202021-01-12 18:10:59 -08003539 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003540 case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3541 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3542 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3543 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3544 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003545 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003546 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003547 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003548 } else {
3549 if dh.pmConfigs.Grouped { // metrics are managed as a group
3550 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003551 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003552
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003553 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3554 // 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 -08003555 // 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 +00003556 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3557 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003558 }
3559 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003560 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3561 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3562 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3563 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003564 }
3565 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003566 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003567
3568 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003569 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3570 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3571 // 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 -08003572 // 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 +00003573 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3574 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003575 }
3576 }
3577 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003578 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3579 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3580 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3581 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003582 }
3583 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003584 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003585 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003586 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003587 } */
3588 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003589 }
3590 }
3591}
kesavandfdf77632021-01-26 23:40:33 -05003592
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003593func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003594
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003595 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3596 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003597}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003598
Himani Chawla43f95ff2021-06-03 00:24:12 +05303599func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3600 if dh.pOnuMetricsMgr == nil {
3601 return &extension.SingleGetValueResponse{
3602 Response: &extension.GetValueResponse{
3603 Status: extension.GetValueResponse_ERROR,
3604 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3605 },
3606 }
3607 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303608 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303609 return resp
3610}
3611
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003612func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3613 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003614 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003615 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003616 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003617}
3618
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003619func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003620 var pAdapterFsm *cmn.AdapterFsm
3621 //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 +00003622 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003623 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003624 {
mpagenkofbf577d2021-10-12 11:44:33 +00003625 if dh.pOnuOmciDevice != nil {
3626 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3627 } else {
3628 return true //FSM not active - so there is no activity on omci
3629 }
mpagenkof1fc3862021-02-16 10:09:52 +00003630 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003631 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003632 {
mpagenkofbf577d2021-10-12 11:44:33 +00003633 if dh.pOnuOmciDevice != nil {
3634 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3635 } else {
3636 return true //FSM not active - so there is no activity on omci
3637 }
mpagenkof1fc3862021-02-16 10:09:52 +00003638 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003639 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003640 {
mpagenkofbf577d2021-10-12 11:44:33 +00003641 if dh.pLockStateFsm != nil {
3642 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3643 } else {
3644 return true //FSM not active - so there is no activity on omci
3645 }
mpagenkof1fc3862021-02-16 10:09:52 +00003646 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003647 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003648 {
mpagenkofbf577d2021-10-12 11:44:33 +00003649 if dh.pUnlockStateFsm != nil {
3650 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3651 } else {
3652 return true //FSM not active - so there is no activity on omci
3653 }
mpagenkof1fc3862021-02-16 10:09:52 +00003654 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003655 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003656 {
mpagenkofbf577d2021-10-12 11:44:33 +00003657 if dh.pOnuMetricsMgr != nil {
3658 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003659 } else {
3660 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003661 }
3662 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003663 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003664 {
3665 dh.lockUpgradeFsm.RLock()
3666 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003667 if dh.pOnuUpradeFsm != nil {
3668 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3669 } else {
3670 return true //FSM not active - so there is no activity on omci
3671 }
mpagenko80622a52021-02-09 16:53:23 +00003672 }
mpagenkof1fc3862021-02-16 10:09:52 +00003673 default:
3674 {
3675 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003676 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003677 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003678 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003679 }
mpagenkofbf577d2021-10-12 11:44:33 +00003680 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3681 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3682 }
3683 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003684}
3685
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003686func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3687 for _, v := range dh.pOnuTP.PAniConfigFsm {
3688 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003689 return false
3690 }
3691 }
3692 return true
3693}
3694
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003695func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003696 dh.lockVlanConfig.RLock()
3697 defer dh.lockVlanConfig.RUnlock()
3698 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003699 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003700 return false
3701 }
3702 }
3703 return true //FSM not active - so there is no activity on omci
3704}
3705
3706func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3707 dh.lockVlanConfig.RLock()
3708 defer dh.lockVlanConfig.RUnlock()
3709 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003710 if v.PAdaptFsm.PFsm != nil {
3711 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003712 return true //there is at least one VLAN FSM with some active configuration
3713 }
3714 }
3715 }
3716 return false //there is no VLAN FSM with some active configuration
3717}
3718
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003719func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003720 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3721 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3722 return false
3723 }
3724 }
3725 // a further check is done to identify, if at least some data traffic related configuration exists
3726 // 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])
3727 return dh.checkUserServiceExists(ctx)
3728}
3729
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003730func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003731 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3732 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003733 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003734 // TODO: fatal error reset ONU, delete deviceHandler!
3735 return
3736 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003737 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
3738 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003739}
3740
3741func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3742 dh.mutexCollectorFlag.Lock()
3743 dh.collectorIsRunning = flagValue
3744 dh.mutexCollectorFlag.Unlock()
3745}
3746
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003747func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003748 dh.mutexCollectorFlag.RLock()
3749 flagValue := dh.collectorIsRunning
3750 dh.mutexCollectorFlag.RUnlock()
3751 return flagValue
3752}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303753
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303754func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3755 dh.mutextAlarmManagerFlag.Lock()
3756 dh.alarmManagerIsRunning = flagValue
3757 dh.mutextAlarmManagerFlag.Unlock()
3758}
3759
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003760func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303761 dh.mutextAlarmManagerFlag.RLock()
3762 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303763 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303764 dh.mutextAlarmManagerFlag.RUnlock()
3765 return flagValue
3766}
3767
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003768func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303769 logger.Debugf(ctx, "startingAlarmManager")
3770
3771 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003772 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303773 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303774 if stop := <-dh.stopAlarmManager; stop {
3775 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303776 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303777 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003778 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
3779 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05303780 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303781 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003782 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
3783 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05303784 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303785 }
3786}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003787
Girish Gowdrae95687a2021-09-08 16:30:58 -07003788func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
3789 dh.mutexFlowMonitoringRoutineFlag.Lock()
3790 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
3791 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"flag": flag})
3792 dh.isFlowMonitoringRoutineActive[uniID] = flag
3793}
3794
3795func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
3796 dh.mutexFlowMonitoringRoutineFlag.RLock()
3797 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
3798 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
3799 log.Fields{"isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
3800 return dh.isFlowMonitoringRoutineActive[uniID]
3801}
3802
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003803func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
3804 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003805
Maninder7961d722021-06-16 22:10:28 +05303806 connectStatus := voltha.ConnectStatus_UNREACHABLE
3807 operState := voltha.OperStatus_UNKNOWN
3808
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003809 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003810 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003811 logger.Debugw(ctx, "wait for channel signal or timeout",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003812 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003813 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003814 case success := <-dh.chReconcilingFinished:
3815 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003816 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05303817 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003818 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05303819 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003820 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05303821 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003822 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
3823 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05303824 operState = voltha.OperStatus_ACTIVE
3825 } else {
3826 operState = voltha.OperStatus_ACTIVATING
3827 }
3828 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003829 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
3830 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
3831 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05303832 operState = voltha.OperStatus_DISCOVERED
3833 }
3834
3835 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303836 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003837 logger.Debugw(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003838 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04003839 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003840 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003841 ConnStatus: connectStatus,
3842 OperStatus: operState,
3843 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05303844 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003845 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05303846 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003847 } else {
Maninderb5187552021-03-23 22:23:42 +05303848 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003849 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05303850
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003851 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05303852 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003853 log.Fields{"device-id": dh.DeviceID})
3854 } else if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninder7961d722021-06-16 22:10:28 +05303855 connectStatus = voltha.ConnectStatus_REACHABLE
3856 }
3857
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003858 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003859 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003860 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003861 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003862 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05303863
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003864 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05303865 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003866 log.Fields{"device-id": dh.DeviceID})
3867 } else if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninder7961d722021-06-16 22:10:28 +05303868 connectStatus = voltha.ConnectStatus_REACHABLE
3869 }
3870
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003871 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05303872
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003873 }
3874 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003875 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003876 dh.mutexReconcilingFlag.Unlock()
3877 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003878 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003879 dh.mutexReconcilingFlag.Lock()
3880 if skipOnuConfig {
3881 dh.reconciling = cSkipOnuConfigReconciling
3882 } else {
3883 dh.reconciling = cOnuConfigReconciling
3884 }
3885 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003886}
3887
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003888func (dh *deviceHandler) StopReconciling(ctx context.Context, success bool) {
3889 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
3890 if dh.IsReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07003891 dh.chReconcilingFinished <- success
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003892 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003893 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003894 }
3895}
3896
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003897func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003898 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003899 defer dh.mutexReconcilingFlag.RUnlock()
3900 return dh.reconciling != cNoReconciling
3901}
3902
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003903func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003904 dh.mutexReconcilingFlag.RLock()
3905 defer dh.mutexReconcilingFlag.RUnlock()
3906 return dh.reconciling == cSkipOnuConfigReconciling
3907}
3908
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003909func (dh *deviceHandler) SetDeviceReason(value uint8) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003910 dh.mutexDeviceReason.Lock()
3911 dh.deviceReason = value
3912 dh.mutexDeviceReason.Unlock()
3913}
3914
3915func (dh *deviceHandler) getDeviceReason() uint8 {
3916 dh.mutexDeviceReason.RLock()
3917 value := dh.deviceReason
3918 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003919 return value
3920}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003921
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003922func (dh *deviceHandler) GetDeviceReasonString() string {
3923 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003924}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003925
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003926func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003927 dh.mutexReadyForOmciConfig.Lock()
3928 dh.readyForOmciConfig = flagValue
3929 dh.mutexReadyForOmciConfig.Unlock()
3930}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003931func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003932 dh.mutexReadyForOmciConfig.RLock()
3933 flagValue := dh.readyForOmciConfig
3934 dh.mutexReadyForOmciConfig.RUnlock()
3935 return flagValue
3936}
Maninder7961d722021-06-16 22:10:28 +05303937
3938func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
3939 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
3940 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003941 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05303942 }
3943
3944 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04003945 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003946 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003947 ConnStatus: connectStatus,
3948 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
3949 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05303950 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003951 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05303952 }
3953}
khenaidoo7d3c5582021-08-11 18:09:44 -04003954
3955/*
3956Helper functions to communicate with Core
3957*/
3958
3959func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
3960 cClient, err := dh.coreClient.GetCoreServiceClient()
3961 if err != nil || cClient == nil {
3962 return nil, err
3963 }
3964 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3965 defer cancel()
3966 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
3967 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
3968}
3969
khenaidoo42dcdfd2021-10-19 17:34:12 -04003970func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04003971 cClient, err := dh.coreClient.GetCoreServiceClient()
3972 if err != nil || cClient == nil {
3973 return err
3974 }
3975 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3976 defer cancel()
3977 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
3978 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-state": deviceStateFilter, "error": err})
3979 return err
3980}
3981
3982func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3983 cClient, err := dh.coreClient.GetCoreServiceClient()
3984 if err != nil || cClient == nil {
3985 return err
3986 }
3987 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3988 defer cancel()
3989 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
3990 logger.Debugw(subCtx, "pmconfig-updated-in-core", log.Fields{"pm-configs": pmConfigs, "error": err})
3991 return err
3992}
3993
3994func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
3995 cClient, err := dh.coreClient.GetCoreServiceClient()
3996 if err != nil || cClient == nil {
3997 return err
3998 }
3999 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4000 defer cancel()
4001 _, err = cClient.DeviceUpdate(subCtx, device)
4002 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4003 return err
4004}
4005
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004006func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004007 cClient, err := dh.coreClient.GetCoreServiceClient()
4008 if err != nil || cClient == nil {
4009 return err
4010 }
4011 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4012 defer cancel()
4013 _, err = cClient.PortCreated(subCtx, port)
4014 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4015 return err
4016}
4017
khenaidoo42dcdfd2021-10-19 17:34:12 -04004018func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004019 cClient, err := dh.coreClient.GetCoreServiceClient()
4020 if err != nil || cClient == nil {
4021 return err
4022 }
4023 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4024 defer cancel()
4025 _, err = cClient.PortStateUpdate(subCtx, portState)
4026 logger.Debugw(subCtx, "port-state-updated-in-core", log.Fields{"port-state": portState, "error": err})
4027 return err
4028}
4029
khenaidoo42dcdfd2021-10-19 17:34:12 -04004030func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004031 cClient, err := dh.coreClient.GetCoreServiceClient()
4032 if err != nil || cClient == nil {
4033 return err
4034 }
4035 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4036 defer cancel()
4037 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
4038 logger.Debugw(subCtx, "device-reason-updated-in-core", log.Fields{"reason": reason, "error": err})
4039 return err
4040}
4041
4042/*
4043Helper functions to communicate with parent adapter
4044*/
4045
4046func (dh *deviceHandler) getTechProfileInstanceFromParentAdapter(ctx context.Context, parentEndpoint string,
khenaidoo42dcdfd2021-10-19 17:34:12 -04004047 request *ia.TechProfileInstanceRequestMessage) (*ia.TechProfileDownloadMessage, error) {
khenaidoo7d3c5582021-08-11 18:09:44 -04004048 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4049 if err != nil || pgClient == nil {
4050 return nil, err
4051 }
4052 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4053 defer cancel()
4054 logger.Debugw(subCtx, "get-tech-profile-instance", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4055 return pgClient.GetTechProfileInstance(subCtx, request)
4056}
4057
Girish Gowdrae95687a2021-09-08 16:30:58 -07004058// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4059// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4060func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4061 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4062 dh.setFlowMonitoringIsRunning(uniID, true)
4063 for {
4064 select {
4065 // block on the channel to receive an incoming flow
4066 // process the flow completely before proceeding to handle the next flow
4067 case flowCb := <-dh.flowCbChan[uniID]:
4068 startTime := time.Now()
4069 logger.Debugw(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
4070 respChan := make(chan error)
4071 if flowCb.addFlow {
4072 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4073 } else {
4074 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4075 }
4076 // Block on response and tunnel it back to the caller
4077 *flowCb.respChan <- <-respChan
4078 logger.Debugw(flowCb.ctx, "serial-flow-processor--end",
4079 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4080 case <-dh.stopFlowMonitoringRoutine[uniID]:
4081 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4082 dh.setFlowMonitoringIsRunning(uniID, false)
4083 return
4084 }
4085 }
4086}
4087
khenaidoo42dcdfd2021-10-19 17:34:12 -04004088func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004089 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4090 if err != nil || pgClient == nil {
4091 return err
4092 }
4093 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4094 defer cancel()
4095 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4096 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4097 if err != nil {
4098 logger.Errorw(ctx, "omci-failure", log.Fields{"request": request, "error": err, "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
4099 }
4100 return err
4101}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004102
4103// GetDeviceID - TODO: add comment
4104func (dh *deviceHandler) GetDeviceID() string {
4105 return dh.DeviceID
4106}
4107
4108// GetProxyAddressID - TODO: add comment
4109func (dh *deviceHandler) GetProxyAddressID() string {
4110 return dh.device.ProxyAddress.GetDeviceId()
4111}
4112
4113// GetProxyAddressType - TODO: add comment
4114func (dh *deviceHandler) GetProxyAddressType() string {
4115 return dh.device.ProxyAddress.GetDeviceType()
4116}
4117
4118// GetProxyAddress - TODO: add comment
4119func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4120 return dh.device.ProxyAddress
4121}
4122
4123// GetEventProxy - TODO: add comment
4124func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4125 return dh.EventProxy
4126}
4127
4128// GetOmciTimeout - TODO: add comment
4129func (dh *deviceHandler) GetOmciTimeout() int {
4130 return dh.pOpenOnuAc.omciTimeout
4131}
4132
4133// GetAlarmAuditInterval - TODO: add comment
4134func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4135 return dh.pOpenOnuAc.alarmAuditInterval
4136}
4137
4138// GetDlToOnuTimeout4M - TODO: add comment
4139func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4140 return dh.pOpenOnuAc.dlToOnuTimeout4M
4141}
4142
4143// GetUniEntityMap - TODO: add comment
4144func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4145 return &dh.uniEntityMap
4146}
4147
4148// GetPonPortNumber - TODO: add comment
4149func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4150 return &dh.ponPortNumber
4151}
4152
4153// GetUniVlanConfigFsm - TODO: add comment
4154func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004155 dh.lockVlanConfig.RLock()
4156 value := dh.UniVlanConfigFsmMap[uniID]
4157 dh.lockVlanConfig.RUnlock()
4158 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004159}
4160
4161// GetOnuAlarmManager - TODO: add comment
4162func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4163 return dh.pAlarmMgr
4164}
4165
4166// GetOnuMetricsManager - TODO: add comment
4167func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4168 return dh.pOnuMetricsMgr
4169}
4170
4171// GetOnuTP - TODO: add comment
4172func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4173 return dh.pOnuTP
4174}
4175
4176// GetBackendPathPrefix - TODO: add comment
4177func (dh *deviceHandler) GetBackendPathPrefix() string {
4178 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4179}
4180
4181// GetOnuIndication - TODO: add comment
4182func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4183 return dh.pOnuIndication
4184}
4185
4186// RLockMutexDeletionInProgressFlag - TODO: add comment
4187func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4188 dh.mutexDeletionInProgressFlag.RLock()
4189}
4190
4191// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4192func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4193 dh.mutexDeletionInProgressFlag.RUnlock()
4194}
4195
4196// GetDeletionInProgress - TODO: add comment
4197func (dh *deviceHandler) GetDeletionInProgress() bool {
4198 return dh.deletionInProgress
4199}
4200
4201// GetPmConfigs - TODO: add comment
4202func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4203 return dh.pmConfigs
4204}
4205
4206// GetDeviceType - TODO: add comment
4207func (dh *deviceHandler) GetDeviceType() string {
4208 return dh.DeviceType
4209}
4210
4211// GetLogicalDeviceID - TODO: add comment
4212func (dh *deviceHandler) GetLogicalDeviceID() string {
4213 return dh.logicalDeviceID
4214}
4215
4216// GetDevice - TODO: add comment
4217func (dh *deviceHandler) GetDevice() *voltha.Device {
4218 return dh.device
4219}
4220
4221// GetMetricsEnabled - TODO: add comment
4222func (dh *deviceHandler) GetMetricsEnabled() bool {
4223 return dh.pOpenOnuAc.MetricsEnabled
4224}
4225
4226// InitPmConfigs - TODO: add comment
4227func (dh *deviceHandler) InitPmConfigs() {
4228 dh.pmConfigs = &voltha.PmConfigs{}
4229}
4230
4231// GetUniPortMask - TODO: add comment
4232func (dh *deviceHandler) GetUniPortMask() int {
4233 return dh.pOpenOnuAc.config.UniPortMask
4234}