blob: 0203575ffaa3f1872c01a70c9d6ee2c03cb11e00 [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
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000058const (
mpagenko101ac942021-11-16 15:01:29 +000059 //constants for reconcile flow check channel
60 cWaitReconcileFlowAbortOnSuccess = 0xFFFD
61 cWaitReconcileFlowAbortOnError = 0xFFFE
62 cWaitReconcileFlowNoActivity = 0xFFFF
63)
64
65const (
66 // constants for timeouts
mpagenko38662d02021-08-11 09:45:19 +000067 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000068)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000069
mpagenko1cc3cb42020-07-27 15:24:38 +000070const (
mpagenko44bd8362021-11-15 11:40:05 +000071 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
72 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
73 // as long as such is not available by the libraries - use this workaround
74 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
75)
76
77const (
mpagenko1cc3cb42020-07-27 15:24:38 +000078 // events of Device FSM
79 devEvDeviceInit = "devEvDeviceInit"
80 devEvGrpcConnected = "devEvGrpcConnected"
81 devEvGrpcDisconnected = "devEvGrpcDisconnected"
82 devEvDeviceUpInd = "devEvDeviceUpInd"
83 devEvDeviceDownInd = "devEvDeviceDownInd"
84)
85const (
86 // states of Device FSM
87 devStNull = "devStNull"
88 devStDown = "devStDown"
89 devStInit = "devStInit"
90 devStConnected = "devStConnected"
91 devStUp = "devStUp"
92)
93
Holger Hildebrandt24d51952020-05-04 14:03:42 +000094//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
95const (
Himani Chawla4d908332020-08-31 12:30:20 +053096 pon = voltha.EventSubCategory_PON
97 //olt = voltha.EventSubCategory_OLT
98 //ont = voltha.EventSubCategory_ONT
99 //onu = voltha.EventSubCategory_ONU
100 //nni = voltha.EventSubCategory_NNI
101 //service = voltha.EventCategory_SERVICE
102 //security = voltha.EventCategory_SECURITY
103 equipment = voltha.EventCategory_EQUIPMENT
104 //processing = voltha.EventCategory_PROCESSING
105 //environment = voltha.EventCategory_ENVIRONMENT
106 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000107)
108
109const (
110 cEventObjectType = "ONU"
111)
112const (
113 cOnuActivatedEvent = "ONU_ACTIVATED"
114)
115
mpagenkof1fc3862021-02-16 10:09:52 +0000116type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000117 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000118 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000119}
120
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000121var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
122 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
123 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
124 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
125 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
126 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
127 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
128 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
129 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000130}
131
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000132const (
133 cNoReconciling = iota
134 cOnuConfigReconciling
135 cSkipOnuConfigReconciling
136)
137
Girish Gowdrae95687a2021-09-08 16:30:58 -0700138// FlowCb is the flow control block containing flow add/delete information along with a response channel
139type FlowCb struct {
140 ctx context.Context // Flow handler context
141 addFlow bool // if true flow to be added, else removed
142 flowItem *of.OfpFlowStats
143 uniPort *cmn.OnuUniPort
khenaidoo42dcdfd2021-10-19 17:34:12 -0400144 flowMetaData *of.FlowMetadata
Girish Gowdrae95687a2021-09-08 16:30:58 -0700145 respChan *chan error // channel to report the Flow handling error
146}
147
Himani Chawla6d2ae152020-09-02 13:11:20 +0530148//deviceHandler will interact with the ONU ? device.
149type deviceHandler struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000150 DeviceID string
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000151 DeviceType string
152 adminState string
153 device *voltha.Device
154 logicalDeviceID string
155 ProxyAddressID string
156 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530157 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000158 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000159
khenaidoo7d3c5582021-08-11 18:09:44 -0400160 coreClient *vgrpc.Client
161 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000162
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800163 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400164 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800165
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000166 pOpenOnuAc *OpenONUAC
167 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530168 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000169 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000170 pOnuOmciDevice *mib.OnuDeviceEntry
171 pOnuTP *avcfg.OnuUniTechProf
172 pOnuMetricsMgr *pmmgr.OnuMetricsManager
173 pAlarmMgr *almgr.OnuAlarmManager
174 pSelfTestHdlr *otst.SelfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000175 exitChannel chan int
176 lockDevice sync.RWMutex
177 pOnuIndication *oop.OnuIndication
178 deviceReason uint8
179 mutexDeviceReason sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000180 pLockStateFsm *uniprt.LockStateFsm
181 pUnlockStateFsm *uniprt.LockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000182
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000183 //flowMgr *OpenOltFlowMgr
184 //eventMgr *OpenOltEventMgr
185 //resourceMgr *rsrcMgr.OpenOltResourceMgr
186
187 //discOnus sync.Map
188 //onus sync.Map
189 //portStats *OpenOltStatisticsMgr
mpagenko101ac942021-11-16 15:01:29 +0000190 collectorIsRunning bool
191 mutexCollectorFlag sync.RWMutex
192 stopCollector chan bool
193 alarmManagerIsRunning bool
194 mutextAlarmManagerFlag sync.RWMutex
195 stopAlarmManager chan bool
196 stopHeartbeatCheck chan bool
197 uniEntityMap cmn.OnuUniPortMap
198 mutexKvStoreContext sync.Mutex
199 lockVlanConfig sync.RWMutex
200 lockVlanAdd sync.RWMutex
201 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
202 lockUpgradeFsm sync.RWMutex
203 pOnuUpradeFsm *swupg.OnuUpgradeFsm
204 upgradeCanceled bool
205 reconciling uint8
206 mutexReconcilingFlag sync.RWMutex
207 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
208 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
209 reconcileExpiryComplete time.Duration
210 reconcileExpiryVlanConfig time.Duration
211 mutexReadyForOmciConfig sync.RWMutex
212 readyForOmciConfig bool
213 deletionInProgress bool
214 mutexDeletionInProgressFlag sync.RWMutex
215 pLastUpgradeImageState *voltha.ImageState
216 upgradeFsmChan chan struct{}
Girish Gowdrae95687a2021-09-08 16:30:58 -0700217
218 flowCbChan []chan FlowCb
219 mutexFlowMonitoringRoutineFlag sync.RWMutex
220 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
221 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000222}
223
Himani Chawla6d2ae152020-09-02 13:11:20 +0530224//newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400225func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530226 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400227 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000228 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400229 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000230 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000231 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000232 dh.DeviceType = cloned.Type
233 dh.adminState = "up"
234 dh.device = cloned
235 dh.pOpenOnuAc = adapter
236 dh.exitChannel = make(chan int, 1)
237 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000238 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000239 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000240 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530241 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530242 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000243 dh.stopHeartbeatCheck = make(chan bool, 2)
244 //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 +0000245 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000246 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000247 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000248 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000249 dh.lockUpgradeFsm = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000250 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000251 dh.reconciling = cNoReconciling
mpagenko101ac942021-11-16 15:01:29 +0000252 dh.chUniVlanConfigReconcilingDone = make(chan uint16)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000253 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000254 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
255 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
256 if rECSeconds < 2 {
257 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
258 rECSeconds = 2
259 }
260 rEVCSeconds := rECSeconds / 2
261 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000262 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000263 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000264 dh.pLastUpgradeImageState = &voltha.ImageState{
265 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
266 Reason: voltha.ImageState_UNKNOWN_ERROR,
267 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
268 }
269 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000270
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800271 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
272 dh.pmConfigs = cloned.PmConfigs
273 } /* else {
274 // will be populated when onu_metrics_mananger is initialized.
275 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800276
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000277 // Device related state machine
278 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000279 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000280 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000281 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
282 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
283 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
284 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
285 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286 },
287 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000288 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
289 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
290 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
291 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
292 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
293 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
294 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
295 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000296 },
297 )
mpagenkoaf801632020-07-03 10:00:42 +0000298
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000299 return &dh
300}
301
Himani Chawla6d2ae152020-09-02 13:11:20 +0530302// start save the device to the data model
303func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000304 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000305 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000306 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000307}
308
Himani Chawla4d908332020-08-31 12:30:20 +0530309/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000310// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530311func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000312 logger.Debug("stopping-device-handler")
313 dh.exitChannel <- 1
314}
Himani Chawla4d908332020-08-31 12:30:20 +0530315*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000316
317// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530318// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000319
Girish Gowdrae0140f02021-02-02 16:55:09 -0800320//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530321func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400322 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000323
dbainbri4d3a0dc2020-12-02 00:33:42 +0000324 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000325 if dh.pDeviceStateFsm.Is(devStNull) {
326 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000327 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000328 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000329 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800330 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
331 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800332 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400333 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000334 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800335 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800336 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000337 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000338 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000339 }
340
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000341}
342
khenaidoo42dcdfd2021-10-19 17:34:12 -0400343func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000344 /* 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 +0530345 //assuming omci message content is hex coded!
346 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000347 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000348 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000349 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000350 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530351 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000352 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000353 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000354 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400355 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 +0530356 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000357 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
358 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530359}
360
khenaidoo42dcdfd2021-10-19 17:34:12 -0400361func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000362 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000363
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000364 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000365 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000366 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
367 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000368 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530369 if dh.pOnuTP == nil {
370 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000371 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000372 log.Fields{"device-id": dh.DeviceID})
373 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530374 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000375 if !dh.IsReadyForOmciConfig() {
376 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
377 "device-state": dh.GetDeviceReasonString()})
378 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530379 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000380 //previous state test here was just this one, now extended for more states to reject the SetRequest:
381 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
382 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530383
Himani Chawla26e555c2020-08-31 12:30:20 +0530384 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000385 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
386 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000387 dh.pOnuTP.LockTpProcMutex()
388 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000389
mpagenko44bd8362021-11-15 11:40:05 +0000390 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000391 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000392 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000393 }
394 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000395 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800396 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700397 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800398 return err
399 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700400 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000401
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000402 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530403
Girish Gowdra50e56422021-06-01 16:46:04 -0700404 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400405 case *ia.TechProfileDownloadMessage_TpInstance:
Girish Gowdra50e56422021-06-01 16:46:04 -0700406 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
407 // if there has been some change for some uni TechProfilePath
408 //in order to allow concurrent calls to other dh instances we do not wait for execution here
409 //but doing so we can not indicate problems to the caller (who does what with that then?)
410 //by now we just assume straightforward successful execution
411 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
412 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530413
Girish Gowdra50e56422021-06-01 16:46:04 -0700414 // deadline context to ensure completion of background routines waited for
415 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
416 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
417 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000418
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000419 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700420
421 var wg sync.WaitGroup
422 wg.Add(1) // for the 1 go routine to finish
423 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000424 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700425 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000426 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
427 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 -0700428 return tpErr
429 }
430 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
431 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000432 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700433 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000434 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700435 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000436 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
437 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 -0700438 return kvErr
439 }
440 return nil
441 default:
442 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"tp-path": techProfMsg.TpInstancePath})
443 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700444 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530445 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000446 // no change, nothing really to do - return success
Girish Gowdra50e56422021-06-01 16:46:04 -0700447 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 +0530448 return nil
449}
450
khenaidoo42dcdfd2021-10-19 17:34:12 -0400451func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000452 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530453
454 if dh.pOnuTP == nil {
455 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000456 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000457 log.Fields{"device-id": dh.DeviceID})
458 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530459 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530460 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000461 dh.pOnuTP.LockTpProcMutex()
462 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530463
mpagenko0f543222021-11-03 16:24:14 +0000464 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
465 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
466 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000467 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000468 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000469 }
470 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000471 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800472 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000473 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
474 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800475 return err
476 }
mpagenko0f543222021-11-03 16:24:14 +0000477 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
478 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000479 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000480
Mahir Gunyel9545be22021-07-04 15:53:16 -0700481 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000482 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000483
Himani Chawla26e555c2020-08-31 12:30:20 +0530484}
485
khenaidoo42dcdfd2021-10-19 17:34:12 -0400486func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000487 logger.Infow(ctx, "delete-tcont-request start", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000488
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000489 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000490 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000491 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
492 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000493 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530494 if dh.pOnuTP == nil {
495 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000496 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000497 log.Fields{"device-id": dh.DeviceID})
498 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530499 }
500
Himani Chawla26e555c2020-08-31 12:30:20 +0530501 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000502 dh.pOnuTP.LockTpProcMutex()
503 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000504
mpagenko0f543222021-11-03 16:24:14 +0000505 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
506 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
507 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000508 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000509 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000510 }
511 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700512 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000513 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800514 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000515 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
516 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800517 return err
518 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000519 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 +0000520
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000521 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530522
Mahir Gunyel9545be22021-07-04 15:53:16 -0700523 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000524 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000525
Mahir Gunyel9545be22021-07-04 15:53:16 -0700526}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000527
Mahir Gunyel9545be22021-07-04 15:53:16 -0700528func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000529 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
530 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700531 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000532 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
533 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530534 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700535 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000536 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700537 resourceName = "Gem"
538 } else {
539 resourceName = "Tcont"
540 }
541
542 // deadline context to ensure completion of background routines waited for
543 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
544 dctx, cancel := context.WithDeadline(context.Background(), deadline)
545
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000546 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700547
548 var wg sync.WaitGroup
549 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000550 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700551 resource, entryID, &wg)
552 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000553 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
554 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700555 return err
556 }
557
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000558 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
559 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
560 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
561 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700562 var wg2 sync.WaitGroup
563 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
564 wg2.Add(1)
565 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000566 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
567 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700568 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000569 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
570 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700571 return err
572 }
573 }
574 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000575 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700576 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530577 return nil
578}
579
mpagenkodff5dda2020-08-28 11:52:01 +0000580//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000581func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400582 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400583 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700584 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
585 var errorsList []error
586 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000587 //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 +0000588 if apOfFlowChanges.ToRemove != nil {
589 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000590 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000591 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000592 "device-id": dh.DeviceID})
593 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700594 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000595 continue
596 }
597 flowInPort := flow.GetInPort(flowItem)
598 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000599 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
600 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700601 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000602 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000603 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000604 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000605 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000606 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000607 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000608 continue
609 } else {
610 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000611 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000612 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
613 loUniPort = uniPort
614 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000615 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000616 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000617 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000618 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700619 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000620 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000621 }
622 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000623 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000624 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
625 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700626
627 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
628 // Step1 : Fill flowControlBlock
629 // Step2 : Push the flowControlBlock to ONU channel
630 // Step3 : Wait on response channel for response
631 // Step4 : Return error value
632 startTime := time.Now()
633 respChan := make(chan error)
634 flowCb := FlowCb{
635 ctx: ctx,
636 addFlow: false,
637 flowItem: flowItem,
638 flowMetaData: nil,
639 uniPort: loUniPort,
640 respChan: &respChan,
641 }
642 dh.flowCbChan[loUniPort.UniID] <- flowCb
643 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
644 // Wait on the channel for flow handlers return value
645 retError = <-respChan
646 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
647 if retError != nil {
648 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
649 log.Fields{"device-id": dh.DeviceID, "error": retError})
650 errorsList = append(errorsList, retError)
651 continue
652 }
653 } else {
654 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
655 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000656 }
657 }
658 }
659 }
mpagenko01e726e2020-10-23 09:45:29 +0000660 if apOfFlowChanges.ToAdd != nil {
661 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
662 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000663 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000664 "device-id": dh.DeviceID})
665 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700666 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000667 continue
668 }
669 flowInPort := flow.GetInPort(flowItem)
670 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000671 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
672 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700673 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000674 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000675 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000676 } else if flowInPort == dh.ponPortNumber {
677 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000678 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000679 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000680 continue
681 } else {
682 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000683 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000684 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
685 loUniPort = uniPort
686 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000687 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000688 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000689 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000690 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700691 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000692 continue
mpagenko01e726e2020-10-23 09:45:29 +0000693 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000694 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
695 // if not, we just throw some error here to have an indication about that, if we really need to support that
696 // then we would need to create some means to activate the internal stored flows
697 // after the device gets active automatically (and still with its dependency to the TechProfile)
698 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
699 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000700 if !dh.IsReadyForOmciConfig() {
701 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
702 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700703 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
704 errorsList = append(errorsList, retError)
705 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000706 }
707
mpagenko01e726e2020-10-23 09:45:29 +0000708 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000709 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000710 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
711 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700712 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
713 // Step1 : Fill flowControlBlock
714 // Step2 : Push the flowControlBlock to ONU channel
715 // Step3 : Wait on response channel for response
716 // Step4 : Return error value
717 startTime := time.Now()
718 respChan := make(chan error)
719 flowCb := FlowCb{
720 ctx: ctx,
721 addFlow: true,
722 flowItem: flowItem,
723 flowMetaData: apFlowMetaData,
724 uniPort: loUniPort,
725 respChan: &respChan,
726 }
727 dh.flowCbChan[loUniPort.UniID] <- flowCb
728 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
729 // Wait on the channel for flow handlers return value
730 retError = <-respChan
731 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
732 if retError != nil {
733 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
734 log.Fields{"device-id": dh.DeviceID, "error": retError})
735 errorsList = append(errorsList, retError)
736 continue
737 }
738 } else {
739 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
740 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000741 }
742 }
743 }
744 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700745 if len(errorsList) > 0 {
746 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
747 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
748 }
749 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000750}
751
Himani Chawla6d2ae152020-09-02 13:11:20 +0530752//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000753//following are the expected device states after this activity:
754//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
755// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000756func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
757 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000758
mpagenko900ee4b2020-10-12 11:56:34 +0000759 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000760 //note that disableDevice sequences in some 'ONU active' state may yield also
761 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000762 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000763 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000764 //disable-device shall be just a UNi/ONU-G related admin state setting
765 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000766
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000767 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000768 // disable UNI ports/ONU
769 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
770 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000771 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000772 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000773 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000774 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000775 }
776 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000777 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000778 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000779 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400780 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000781 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000782 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400783 OperStatus: voltha.OperStatus_UNKNOWN,
784 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000785 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000786 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000787 }
mpagenko01e726e2020-10-23 09:45:29 +0000788 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000789
790 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000791 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000792 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300793 }
794}
795
Himani Chawla6d2ae152020-09-02 13:11:20 +0530796//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000797func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
798 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000799
mpagenkoaa3afe92021-05-21 16:20:58 +0000800 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000801 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
802 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
803 // for real ONU's that should have nearly no influence
804 // Note that for real ONU's there is anyway a problematic situation with following sequence:
805 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
806 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
807 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000808 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000809
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000810 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000811 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000812 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000813 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000814 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000815 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000816 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000817 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300818}
819
dbainbri4d3a0dc2020-12-02 00:33:42 +0000820func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000821 logger.Debugw(ctx, "reconciling - simulate onu indication", 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})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000826 return
827 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000828 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000829 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000830 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000831 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000832 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000833 }
mpagenko101ac942021-11-16 15:01:29 +0000834 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000835 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000836 }
Himani Chawla4d908332020-08-31 12:30:20 +0530837 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000838 pDevEntry.MutexPersOnuConfig.RLock()
839 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
840 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
841 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
842 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
843 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000844 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000845}
846
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000847func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) {
848 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000849
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000850 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000851 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000852 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
853 if !dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +0000854 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000855 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000856 return
857 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000858 dh.pOnuTP.LockTpProcMutex()
859 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000860
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000861 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000862 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000863 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
864 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000865 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000866 log.Fields{"device-id": dh.DeviceID})
867 if !dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +0000868 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000869 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000870 return
871 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000872 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700873 techProfsFound := false
874 techProfInstLoadFailed := false
875outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000876 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000877 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
878 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000879 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000880 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000881 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000882 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000883 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
884 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000885 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000886 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000887 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700888 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800889 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700890 // Request the TpInstance again from the openolt adapter in case of reconcile
khenaidoo7d3c5582021-08-11 18:09:44 -0400891 iaTechTpInst, err := dh.getTechProfileInstanceFromParentAdapter(ctx,
892 dh.device.ProxyAddress.AdapterEndpoint,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400893 &ia.TechProfileInstanceRequestMessage{
khenaidoo7d3c5582021-08-11 18:09:44 -0400894 DeviceId: dh.device.Id,
895 TpInstancePath: uniData.PersTpPathMap[tpID],
896 ParentDeviceId: dh.parentID,
897 ParentPonPort: dh.device.ParentPortNo,
898 OnuId: dh.device.ProxyAddress.OnuId,
899 UniId: uint32(uniData.PersUniID),
900 })
Girish Gowdra50e56422021-06-01 16:46:04 -0700901 if err != nil || iaTechTpInst == nil {
902 logger.Errorw(ctx, "error fetching tp instance",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000903 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 -0700904 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
905 break outerLoop
906 }
907 var tpInst tech_profile.TechProfileInstance
908 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400909 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700910 tpInst = *techTpInst.TpInstance
mpagenko2dc896e2021-08-02 12:03:59 +0000911 logger.Debugw(ctx, "received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000912 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700913 default: // do not support epon or other tech
mpagenko2dc896e2021-08-02 12:03:59 +0000914 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000915 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700916 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
917 break outerLoop
918 }
919
Girish Gowdra041dcb32020-11-16 16:54:30 -0800920 // deadline context to ensure completion of background routines waited for
921 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
922 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000923 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000924
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000925 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800926 var wg sync.WaitGroup
927 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000928 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000929 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000930 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
931 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700932 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
933 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800934 }
mpagenko2dc896e2021-08-02 12:03:59 +0000935 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000936 if len(uniData.PersFlowParams) != 0 {
937 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000938 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000939 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000940 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000941 } // for all UNI entries from SOnuPersistentData
942 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
943 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000944 }
mpagenko2dc896e2021-08-02 12:03:59 +0000945
946 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
947 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
948}
949
950func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
951 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
952 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000953 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000954 log.Fields{"device-id": dh.DeviceID})
955 if !dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +0000956 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000957 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000958 return
959 }
mpagenko2dc896e2021-08-02 12:03:59 +0000960 if abTechProfInstLoadFailed {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000961 dh.SetDeviceReason(cmn.DrTechProfileConfigDownloadFailed)
mpagenko101ac942021-11-16 15:01:29 +0000962 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -0700963 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000964 } else if dh.IsSkipOnuConfigReconciling() {
965 dh.SetDeviceReason(cmn.DrTechProfileConfigDownloadSuccess)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000966 }
mpagenko2dc896e2021-08-02 12:03:59 +0000967 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000968 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000969 log.Fields{"device-id": dh.DeviceID})
970 if !dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +0000971 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000972 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000973 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000974}
975
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000976func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
977 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000978
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000979 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000980 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000981 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
982 if !dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +0000983 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000984 }
mpagenko101ac942021-11-16 15:01:29 +0000985 //else we don't stop the device handler reconciling in constellation with omci configuration
986 // to avoid unintented state update to rwCore due to still running background processes
987 // such is e.g. possible in TT scenarios with multiple techProfiles as currently the end of processing
988 // of all techProfiles is not awaited (ready on first TP done event)
989 // (applicable to all according code points below)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000990 return
991 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000992
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000993 pDevEntry.MutexPersOnuConfig.RLock()
994 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
995 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000996 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000997 log.Fields{"device-id": dh.DeviceID})
998 if !dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +0000999 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001000 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001001 return
1002 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001003 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001004 var uniVlanConfigEntries []uint8
1005 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1006
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001007 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001008 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1009 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001010 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001011 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001012 continue
1013 }
1014 if len(uniData.PersTpPathMap) == 0 {
mpagenko101ac942021-11-16 15:01:29 +00001015 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001016 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001017 // It doesn't make sense to configure any flows if no TPs are available
1018 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001019 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001020 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1021 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001022 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001023 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001024
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001025 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001026 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001027 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001028 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001029 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1030 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
1031 if !dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00001032 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001033 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001034 return
1035 }
mpagenko101ac942021-11-16 15:01:29 +00001036 //needed to split up function due to sca complexity
1037 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1038
mpagenko2dc896e2021-08-02 12:03:59 +00001039 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001040 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001041 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1042 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001043 // this can't be used as global finished reconciling flag because
1044 // assumes is getting called before the state machines for the last flow is completed,
1045 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001046 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1047 } // for all UNI entries from SOnuPersistentData
1048 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001049
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001050 if !flowsFound {
1051 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001052 log.Fields{"device-id": dh.DeviceID})
1053 if !dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00001054 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001055 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001056 return
1057 }
mpagenko101ac942021-11-16 15:01:29 +00001058
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001059 if dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00001060 //only with 'SkipOnuConfig' we need to wait for all finished-signals
1061 // from vlanConfig processing of all UNI's.
1062 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1063 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1064 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1065 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1066 log.Fields{"device-id": dh.DeviceID})
1067 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1068 if pDevEntry != nil {
1069 pDevEntry.SendChReconcilingFlowsFinished(true)
1070 }
1071 } else {
1072 logger.Errorw(ctx, "timeout waiting for reconciling flows for all UNI's to be finished!",
1073 log.Fields{"device-id": dh.DeviceID})
1074 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1075 if pDevEntry != nil {
1076 pDevEntry.SendChReconcilingFlowsFinished(false)
1077 }
1078 return
1079 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001080 dh.SetDeviceReason(cmn.DrOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001081 }
1082}
1083
mpagenko101ac942021-11-16 15:01:29 +00001084func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1085 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1086 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1087 flowsProcessed := 0
1088 lastFlowToReconcile := false
1089 loUniID := apUniPort.UniID
1090 for _, flowData := range aPersFlowParam {
1091 if dh.IsSkipOnuConfigReconciling() {
1092 if !(*apFlowsFound) {
1093 *apFlowsFound = true
1094 syncChannel := make(chan struct{})
1095 // start go routine with select() on reconciling vlan config channel before
1096 // starting vlan config reconciling process to prevent loss of any signal
1097 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1098 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1099 //block until the wait routine is really blocked on channel input
1100 // in order to prevent to early ready signal from VlanConfig processing
1101 <-syncChannel
1102 }
1103 if flowsProcessed == len(aPersFlowParam)-1 {
1104 var uniAdded bool
1105 lastFlowToReconcile = true
1106 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1107 apWaitGroup.Add(1) //increment the waiting group
1108 }
1109 }
1110 }
1111 // note for above block: also lastFlowToReconcile (as parameter to flow config below)
1112 // is only relevant in the vlanConfig processing for IsSkipOnuConfigReconciling = true
1113 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1114 "device-id": dh.DeviceID, "uni-id": loUniID,
1115 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1116 dh.lockVlanConfig.Lock()
1117 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1118 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1119 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
1120 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1121 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter, nil); err != nil {
1122 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1123 }
1124 } else {
1125 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
1126 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1127 uint8(flowData.VlanRuleParams.SetPcp), cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
1128 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1129 }
1130 }
1131 dh.lockVlanConfig.Unlock()
1132 flowsProcessed++
1133 } //for all flows of this UNI
1134}
1135
1136//waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1137// and decrements the according handler wait group waiting for these indications
1138func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1139 waitGroup *cmn.WaitGroupWithTimeOut) {
1140 var reconciledUniVlanConfigEntries []uint8
1141 var appended bool
1142 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1143 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1144 "device-id": dh.DeviceID, "expiry": expiry})
1145 // indicate blocking on channel now to the caller
1146 aSyncChannel <- struct{}{}
1147 for {
1148 select {
1149 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1150 switch uniIndication {
1151 // no activity requested (should normally not be received) - just continue waiting
1152 case cWaitReconcileFlowNoActivity:
1153 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1154 case cWaitReconcileFlowAbortOnError:
1155 logger.Debugw(ctx, "waitReconcileFlow aborted on error",
1156 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1157 return
1158 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1159 case cWaitReconcileFlowAbortOnSuccess:
1160 logger.Debugw(ctx, "waitReconcileFlow aborted on success",
1161 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1162 return
1163 // this should be a valid UNI vlan config done indication
1164 default:
1165 if uniIndication < platform.MaxUnisPerOnu {
1166 logger.Debugw(ctx, "reconciling flows has been finished in time for this UNI",
1167 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1168 if reconciledUniVlanConfigEntries, appended =
1169 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1170 waitGroup.Done()
1171 }
1172 } else {
1173 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored",
1174 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1175 }
1176 } //switch uniIndication
1177
1178 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1179 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1180 log.Fields{"device-id": dh.DeviceID})
1181 return
1182 }
1183 }
1184}
1185
1186func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1187 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1188}
1189
1190func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1191 for _, ele := range slice {
1192 if ele == val {
1193 return slice, false
1194 }
1195 }
1196 return append(slice, val), true
1197}
1198
1199// sendChReconcileFinished - sends true or false on reconcileFinish channel
1200func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1201 if dh != nil { //if the object still exists (might have been already deleted in background)
1202 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1203 select {
1204 case dh.chReconcilingFinished <- success:
1205 default:
1206 }
1207 }
1208}
1209
1210// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1211func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1212 if dh != nil { //if the object still exists (might have been already deleted in background)
1213 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1214 select {
1215 case dh.chUniVlanConfigReconcilingDone <- value:
1216 default:
1217 }
1218 }
1219}
1220
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001221func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001222 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001223 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001224}
1225
dbainbri4d3a0dc2020-12-02 00:33:42 +00001226func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001227 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001228
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001229 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001230 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001231 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001232 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001233 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001234 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001235
1236 // deadline context to ensure completion of background routines waited for
1237 //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 +05301238 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001239 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001240
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001241 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001242
1243 var wg sync.WaitGroup
1244 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001245 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001246 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001247
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001248 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001249 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001250}
1251
mpagenko15ff4a52021-03-02 10:09:20 +00001252//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1253// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001254// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001255//was and is called in background - error return does not make sense
1256func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001257 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001258 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001259 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001260 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001261 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001262 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301263 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001264 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001265 return
Himani Chawla4d908332020-08-31 12:30:20 +05301266 }
mpagenko01e726e2020-10-23 09:45:29 +00001267
1268 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001269 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001270
mpagenko44bd8362021-11-15 11:40:05 +00001271 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001272 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001273 // do not set the ConnStatus here as it may conflict with the parallel setting from ONU down indication (updateInterface())
khenaidoo42dcdfd2021-10-19 17:34:12 -04001274 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001275 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001276 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001277 OperStatus: voltha.OperStatus_DISCOVERED,
1278 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001279 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001280 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001281 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001282 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001283 if err := dh.deviceReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001284 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001285 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001286 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001287 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1288 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1289 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1290 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001291}
1292
mpagenkoc8bba412021-01-15 15:38:44 +00001293//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001294// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001295func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001296 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001297 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001298 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001299
1300 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001301 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001302 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001303 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1304 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001305 }
1306
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001307 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001308 var inactiveImageID uint16
1309 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1310 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001311 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1312 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001313 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001314 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001315 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001316 if err == nil {
1317 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1318 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001319 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001320 }
1321 } else {
1322 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001323 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001324 }
mpagenko15ff4a52021-03-02 10:09:20 +00001325 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001326 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001327 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001328 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1329 dh.upgradeCanceled = true
1330 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1331 }
mpagenko38662d02021-08-11 09:45:19 +00001332 //no effort spent anymore for the old API to automatically cancel and restart the download
1333 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001334 }
mpagenko15ff4a52021-03-02 10:09:20 +00001335 } else {
1336 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001337 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001338 }
1339 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001340 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1341 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001342 }
1343 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001344}
1345
mpagenkoc26d4c02021-05-06 14:27:57 +00001346//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1347// after the OnuImage has been downloaded to the adapter, called in background
1348func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001349 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001350
1351 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001352 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001353 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001354 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001355 return
1356 }
1357
1358 var inactiveImageID uint16
1359 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1360 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001361 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001362
mpagenko59862f02021-10-11 08:53:18 +00001363 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001364 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001365 // but must be still locked at calling createOnuUpgradeFsm
1366 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1367 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1368 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001369 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1370 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001371 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001372 //flush the remove upgradeFsmChan channel
1373 select {
1374 case <-dh.upgradeFsmChan:
1375 logger.Debug(ctx, "flushed-upgrade-fsm-channel")
1376 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001377 }
mpagenko59862f02021-10-11 08:53:18 +00001378 dh.lockUpgradeFsm.Unlock()
1379 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1380 dh.upgradeCanceled = true
1381 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1382 }
mpagenko38662d02021-08-11 09:45:19 +00001383 select {
1384 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001385 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001386 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1387 return
1388 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001389 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001390 }
mpagenko59862f02021-10-11 08:53:18 +00001391 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001392 }
mpagenko38662d02021-08-11 09:45:19 +00001393
1394 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001395 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001396 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001397 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001398 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001399 if err == nil {
1400 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1401 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1402 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001403 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001404 return
1405 }
mpagenko38662d02021-08-11 09:45:19 +00001406 } else {
1407 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001408 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001409 }
1410 return
1411 }
1412 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001413 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001414}
1415
1416//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001417func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1418 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001419 var err error
1420 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1421 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1422 // 2.) activation of the inactive image
1423
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001424 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001425 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001426 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1427 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001428 }
1429 dh.lockUpgradeFsm.RLock()
1430 if dh.pOnuUpradeFsm != nil {
1431 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001432 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001433 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001434 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1435 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001436 }
mpagenko59862f02021-10-11 08:53:18 +00001437 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1438 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1439 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1440 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001441 // use the OnuVendor identification from this device for the internal unique name
1442 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001443 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001444 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001445 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001446 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001447 "device-id": dh.DeviceID, "error": err})
1448 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001449 }
mpagenko183647c2021-06-08 15:25:04 +00001450 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001451 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001452 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001453 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001454 } //else
1455 dh.lockUpgradeFsm.RUnlock()
1456
1457 // 2.) check if requested image-version equals the inactive one and start its activation
1458 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1459 var inactiveImageID uint16
1460 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1461 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001462 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1463 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001464 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001465 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001466 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001467 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001468 if err == nil {
1469 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1470 inactiveImageID, aCommitRequest); err != nil {
1471 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001472 "device-id": dh.DeviceID, "error": err})
1473 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001474 }
1475 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001476 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001477 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001478 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001479 } //else
1480 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001481 "device-id": dh.DeviceID, "error": err})
1482 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001483}
1484
1485//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001486func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1487 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001488 var err error
1489 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1490 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1491 // 2.) commitment of the active image
1492
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001493 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001494 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001495 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1496 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001497 }
1498 dh.lockUpgradeFsm.RLock()
1499 if dh.pOnuUpradeFsm != nil {
1500 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001501 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001502 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001503 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1504 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001505 }
mpagenko59862f02021-10-11 08:53:18 +00001506 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1507 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1508 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1509 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001510 // use the OnuVendor identification from this device for the internal unique name
1511 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001512 // 1.) check a started upgrade process and relay the commitment request to it
1513 // the running upgrade may be based either on the imageIdentifier (started from download)
1514 // or on the imageVersion (started from pure activation)
1515 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1516 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001517 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001518 "device-id": dh.DeviceID, "error": err})
1519 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001520 }
mpagenko183647c2021-06-08 15:25:04 +00001521 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001522 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001523 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001524 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001525 } //else
1526 dh.lockUpgradeFsm.RUnlock()
1527
mpagenko183647c2021-06-08 15:25:04 +00001528 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001529 var activeImageID uint16
1530 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1531 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001532 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1533 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001534 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001535 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001536 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001537 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001538 if err == nil {
1539 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1540 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001541 "device-id": dh.DeviceID, "error": err})
1542 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001543 }
1544 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001545 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001546 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001547 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001548 } //else
1549 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001550 "device-id": dh.DeviceID, "error": err})
1551 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001552}
1553
mpagenkoaa3afe92021-05-21 16:20:58 +00001554func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001555 aVersion string) *voltha.ImageState {
1556 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001557 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001558 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001559 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001560 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1561 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1562 if aVersion == dh.pLastUpgradeImageState.Version {
1563 pImageState = dh.pLastUpgradeImageState
1564 } else { //state request for an image version different from last processed image version
1565 pImageState = &voltha.ImageState{
1566 Version: aVersion,
1567 //we cannot state something concerning this version
1568 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1569 Reason: voltha.ImageState_NO_ERROR,
1570 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1571 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001572 }
1573 }
mpagenko38662d02021-08-11 09:45:19 +00001574 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001575}
1576
1577func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1578 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001579 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001580 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001581 dh.lockUpgradeFsm.RLock()
1582 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001583 dh.lockUpgradeFsm.RUnlock()
1584 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001585 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001586 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1587 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1588 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1589 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1590 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1591 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001592 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1593 dh.upgradeCanceled = true
1594 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1595 }
mpagenko45586762021-10-01 08:30:22 +00001596 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001597 } else {
mpagenko45586762021-10-01 08:30:22 +00001598 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001599 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1600 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1601 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1602 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1603 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1604 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001605 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1606 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001607 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1608 //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 +00001609 }
1610}
1611
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001612func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1613
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001614 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001615
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001616 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001617 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001618 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1619 pDevEntry.MutexOnuImageStatus.Lock()
1620 pDevEntry.POnuImageStatus = onuImageStatus
1621 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001622
1623 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001624 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001625 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1626 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001627 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1628 pDevEntry.MutexOnuImageStatus.Lock()
1629 pDevEntry.POnuImageStatus = nil
1630 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001631 return images, err
1632}
1633
Himani Chawla6d2ae152020-09-02 13:11:20 +05301634// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001635// #####################################################################################
1636
1637// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301638// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001639
dbainbri4d3a0dc2020-12-02 00:33:42 +00001640func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001641 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 +00001642}
1643
1644// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001645func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001646
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001648 var err error
1649
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001650 // populate what we know. rest comes later after mib sync
1651 dh.device.Root = false
1652 dh.device.Vendor = "OpenONU"
1653 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001654 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
1655 dh.SetDeviceReason(cmn.DrActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001656
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001657 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001658
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001659 if !dh.IsReconciling() {
1660 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001661 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1662 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1663 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301664 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001665 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001666 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001667 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001668 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001669
Himani Chawla4d908332020-08-31 12:30:20 +05301670 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001671 dh.ponPortNumber = dh.device.ParentPortNo
1672
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001673 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1674 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1675 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001676 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001677 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301678 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001679
1680 /*
1681 self._pon = PonPort.create(self, self._pon_port_number)
1682 self._pon.add_peer(self.parent_id, self._pon_port_number)
1683 self.logger.debug('adding-pon-port-to-agent',
1684 type=self._pon.get_port().type,
1685 admin_state=self._pon.get_port().admin_state,
1686 oper_status=self._pon.get_port().oper_status,
1687 )
1688 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001689 if !dh.IsReconciling() {
1690 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001691 var ponPortNo uint32 = 1
1692 if dh.ponPortNumber != 0 {
1693 ponPortNo = dh.ponPortNumber
1694 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001695
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001696 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001697 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001698 PortNo: ponPortNo,
1699 Label: fmt.Sprintf("pon-%d", ponPortNo),
1700 Type: voltha.Port_PON_ONU,
1701 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301702 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001703 PortNo: ponPortNo}}, // Peer port is parent's port number
1704 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001705 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001706 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001707 e.Cancel(err)
1708 return
1709 }
1710 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001711 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001712 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001713 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001714}
1715
1716// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001717func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001718
dbainbri4d3a0dc2020-12-02 00:33:42 +00001719 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001720 var err error
1721 /*
1722 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1723 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1724 return nil
1725 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001726 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1727 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001728 e.Cancel(err)
1729 return
1730 }
1731
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001732 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001733 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001734 // reconcilement will be continued after mib download is done
1735 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001736
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001737 /*
1738 ############################################################################
1739 # Setup Alarm handler
1740 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1741 device.serial_number)
1742 ############################################################################
1743 # Setup PM configuration for this device
1744 # Pass in ONU specific options
1745 kwargs = {
1746 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1747 'heartbeat': self.heartbeat,
1748 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1749 }
1750 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1751 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1752 self.logical_device_id, device.serial_number,
1753 grouped=True, freq_override=False, **kwargs)
1754 pm_config = self._pm_metrics.make_proto()
1755 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1756 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1757 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1758
1759 # Note, ONU ID and UNI intf set in add_uni_port method
1760 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1761 ani_ports=[self._pon])
1762
1763 # Code to Run OMCI Test Action
1764 kwargs_omci_test_action = {
1765 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1766 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1767 }
1768 serial_number = device.serial_number
1769 self._test_request = OmciTestRequest(self.core_proxy,
1770 self.omci_agent, self.device_id,
1771 AniG, serial_number,
1772 self.logical_device_id,
1773 exclusive=False,
1774 **kwargs_omci_test_action)
1775
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001776 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001777 else:
1778 self.logger.info('onu-already-activated')
1779 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001780
dbainbri4d3a0dc2020-12-02 00:33:42 +00001781 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001782}
1783
1784// doStateConnected get the device info and update to voltha core
1785// for comparison of the original method (not that easy to uncomment): compare here:
1786// voltha-openolt-adapter/adaptercore/device_handler.go
1787// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001788func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001789
dbainbri4d3a0dc2020-12-02 00:33:42 +00001790 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301791 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001792 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001793 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001794}
1795
1796// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001797func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001798
dbainbri4d3a0dc2020-12-02 00:33:42 +00001799 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301800 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001801 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001802 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001803
1804 /*
1805 // Synchronous call to update device state - this method is run in its own go routine
1806 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1807 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001808 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 +00001809 return err
1810 }
1811 return nil
1812 */
1813}
1814
1815// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001816func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001817
dbainbri4d3a0dc2020-12-02 00:33:42 +00001818 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001819 var err error
1820
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001821 device := dh.device
1822 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001823 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001824 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001825 e.Cancel(err)
1826 return
1827 }
1828
1829 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001830 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001831 /*
1832 // Update the all ports state on that device to disable
1833 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001834 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001835 return er
1836 }
1837
1838 //Update the device oper state and connection status
1839 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1840 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1841 dh.device = cloned
1842
1843 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001844 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001845 return er
1846 }
1847
1848 //get the child device for the parent device
1849 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1850 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001851 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001852 return err
1853 }
1854 for _, onuDevice := range onuDevices.Items {
1855
1856 // Update onu state as down in onu adapter
1857 onuInd := oop.OnuIndication{}
1858 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001859 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001860 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1861 if er != nil {
1862 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001863 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001864 //Do not return here and continue to process other ONUs
1865 }
1866 }
1867 // * Discovered ONUs entries need to be cleared , since after OLT
1868 // is up, it starts sending discovery indications again* /
1869 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001870 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001871 return nil
1872 */
Himani Chawla4d908332020-08-31 12:30:20 +05301873 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001874 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001875 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001876}
1877
Himani Chawla6d2ae152020-09-02 13:11:20 +05301878// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001879// #################################################################################
1880
1881// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301882// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001883
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001884//GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
1885func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001886 dh.lockDevice.RLock()
1887 pOnuDeviceEntry := dh.pOnuOmciDevice
1888 if aWait && pOnuDeviceEntry == nil {
1889 //keep the read sema short to allow for subsequent write
1890 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001891 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001892 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1893 // so it might be needed to wait here for that event with some timeout
1894 select {
1895 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001896 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001897 return nil
1898 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001899 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001900 // if written now, we can return the written value without sema
1901 return dh.pOnuOmciDevice
1902 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001903 }
mpagenko3af1f032020-06-10 08:53:41 +00001904 dh.lockDevice.RUnlock()
1905 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001906}
1907
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001908//setDeviceHandlerEntries sets the ONU device entry within the handler
1909func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1910 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001911 dh.lockDevice.Lock()
1912 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001913 dh.pOnuOmciDevice = apDeviceEntry
1914 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001915 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301916 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001917 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001918}
1919
Himani Chawla6d2ae152020-09-02 13:11:20 +05301920//addOnuDeviceEntry creates a new ONU device or returns the existing
1921func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001922 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001923
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001924 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001925 if deviceEntry == nil {
1926 /* costum_me_map in python code seems always to be None,
1927 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1928 /* also no 'clock' argument - usage open ...*/
1929 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001930 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1931 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1932 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1933 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1934 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001935 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001936 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001937 // fire deviceEntry ready event to spread to possibly waiting processing
1938 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001939 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001940 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001941 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001942 }
1943 // might be updated with some error handling !!!
1944 return nil
1945}
1946
dbainbri4d3a0dc2020-12-02 00:33:42 +00001947func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1948 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001949 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1950
1951 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001952
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001953 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001954 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001955 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1956 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001957 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001958 if !dh.IsReconciling() {
1959 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001960 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001961 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001962 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001963 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001964 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001965
khenaidoo42dcdfd2021-10-19 17:34:12 -04001966 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001967 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001968 OperStatus: voltha.OperStatus_ACTIVATING,
1969 ConnStatus: voltha.ConnectStatus_REACHABLE,
1970 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001971 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001972 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001973 }
1974 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001975 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001976 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001977
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001978 pDevEntry.MutexPersOnuConfig.RLock()
1979 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1980 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001981 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 +00001982 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001983 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001984 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001985 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001986 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001987 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001988 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1989 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1990 // 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 +00001991 // 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 +00001992 // so let's just try to keep it simple ...
1993 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001994 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001995 if err != nil || device == nil {
1996 //TODO: needs to handle error scenarios
1997 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1998 return errors.New("Voltha Device not found")
1999 }
2000 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002001
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002002 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002003 return err
mpagenko3af1f032020-06-10 08:53:41 +00002004 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002005
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002006 _ = dh.deviceReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002007
2008 /* this might be a good time for Omci Verify message? */
2009 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002010 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00002011 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00002012 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002013 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002014
2015 /* give the handler some time here to wait for the OMCi verification result
2016 after Timeout start and try MibUpload FSM anyway
2017 (to prevent stopping on just not supported OMCI verification from ONU) */
2018 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002019 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00002020 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002021 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00002022 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002023 }
2024
2025 /* In py code it looks earlier (on activate ..)
2026 # Code to Run OMCI Test Action
2027 kwargs_omci_test_action = {
2028 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2029 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2030 }
2031 serial_number = device.serial_number
2032 self._test_request = OmciTestRequest(self.core_proxy,
2033 self.omci_agent, self.device_id,
2034 AniG, serial_number,
2035 self.logical_device_id,
2036 exclusive=False,
2037 **kwargs_omci_test_action)
2038 ...
2039 # Start test requests after a brief pause
2040 if not self._test_request_started:
2041 self._test_request_started = True
2042 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2043 reactor.callLater(tststart, self._test_request.start_collector)
2044
2045 */
2046 /* which is then: in omci_test_request.py : */
2047 /*
2048 def start_collector(self, callback=None):
2049 """
2050 Start the collection loop for an adapter if the frequency > 0
2051
2052 :param callback: (callable) Function to call to collect PM data
2053 """
2054 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2055 if callback is None:
2056 callback = self.perform_test_omci
2057
2058 if self.lc is None:
2059 self.lc = LoopingCall(callback)
2060
2061 if self.default_freq > 0:
2062 self.lc.start(interval=self.default_freq / 10)
2063
2064 def perform_test_omci(self):
2065 """
2066 Perform the initial test request
2067 """
2068 ani_g_entities = self._device.configuration.ani_g_entities
2069 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2070 is not None else None
2071 self._entity_id = ani_g_entities_ids[0]
2072 self.logger.info('perform-test', entity_class=self._entity_class,
2073 entity_id=self._entity_id)
2074 try:
2075 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2076 result = yield self._device.omci_cc.send(frame)
2077 if not result.fields['omci_message'].fields['success_code']:
2078 self.logger.info('Self-Test Submitted Successfully',
2079 code=result.fields[
2080 'omci_message'].fields['success_code'])
2081 else:
2082 raise TestFailure('Test Failure: {}'.format(
2083 result.fields['omci_message'].fields['success_code']))
2084 except TimeoutError as e:
2085 self.deferred.errback(failure.Failure(e))
2086
2087 except Exception as e:
2088 self.logger.exception('perform-test-Error', e=e,
2089 class_id=self._entity_class,
2090 entity_id=self._entity_id)
2091 self.deferred.errback(failure.Failure(e))
2092
2093 */
2094
2095 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002096 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002097
mpagenko1cc3cb42020-07-27 15:24:38 +00002098 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2099 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2100 * 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 +05302101 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002102 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002103 //call MibUploadFSM - transition up to state UlStInSync
2104 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002105 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002106 if pMibUlFsm.Is(mib.UlStDisabled) {
2107 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2108 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2109 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302110 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002111 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302112 //Determine ONU status and start/re-start MIB Synchronization tasks
2113 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002114 if pDevEntry.IsNewOnu() {
2115 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2116 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2117 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002118 }
Himani Chawla4d908332020-08-31 12:30:20 +05302119 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002120 if err := pMibUlFsm.Event(mib.UlEvExamineMds); err != nil {
2121 logger.Errorw(ctx, "MibSyncFsm: Can't go to state examine_mds", log.Fields{"device-id": dh.DeviceID, "err": err})
2122 return fmt.Errorf("can't go to examine_mds: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302123 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002124 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002125 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002126 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002127 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002128 "device-id": dh.DeviceID})
2129 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002130 }
2131 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002132 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2133 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002134 }
2135 return nil
2136}
2137
dbainbri4d3a0dc2020-12-02 00:33:42 +00002138func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00002139 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002140 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002141 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
2142 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002143
mpagenko900ee4b2020-10-12 11:56:34 +00002144 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2145 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2146 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002147 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002148 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002149 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002150 // abort: system behavior is just unstable ...
2151 return err
2152 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002153 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002154 _ = 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 +00002155
2156 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002157 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002158 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002159 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002160 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2161 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002162 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002163 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002164
2165 //TODO!!! remove existing traffic profiles
2166 /* from py code, if TP's exist, remove them - not yet implemented
2167 self._tp = dict()
2168 # Let TP download happen again
2169 for uni_id in self._tp_service_specific_task:
2170 self._tp_service_specific_task[uni_id].clear()
2171 for uni_id in self._tech_profile_download_done:
2172 self._tech_profile_download_done[uni_id].clear()
2173 */
2174
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002175 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002176
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002177 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002178
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002179 if err := dh.deviceReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002180 // abort: system behavior is just unstable ...
2181 return err
2182 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002183 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002184 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002185 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002186 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002187 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2188 OperStatus: voltha.OperStatus_DISCOVERED,
2189 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002190 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002191 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002192 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002193 // abort: system behavior is just unstable ...
2194 return err
2195 }
2196 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002197 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002198 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002199 return nil
2200}
2201
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002202func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002203 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2204 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2205 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2206 // and using the stop/reset event should never harm
2207
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002208 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002209 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002210 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2211 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00002212 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002213 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002214 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002215 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002216 pDevEntry.MutexOnuImageStatus.RLock()
2217 if pDevEntry.POnuImageStatus != nil {
2218 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002219 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002220 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002221
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002222 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002223 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002224 }
2225 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002226 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002227 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002228 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002229 }
mpagenko101ac942021-11-16 15:01:29 +00002230 //stop any deviceHandler reconcile processing (if running)
2231 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002232 //port lock/unlock FSM's may be active
2233 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002234 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002235 }
2236 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002237 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002238 }
2239 //techProfile related PonAniConfigFsm FSM may be active
2240 if dh.pOnuTP != nil {
2241 // should always be the case here
2242 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002243 if dh.pOnuTP.PAniConfigFsm != nil {
2244 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2245 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002246 }
mpagenko900ee4b2020-10-12 11:56:34 +00002247 }
2248 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002249 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002250 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002251 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002252 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002253 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002254 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002255 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002256 } else {
2257 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002258 }
2259 }
2260 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002261 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002262 // Stop collector routine
2263 dh.stopCollector <- true
2264 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002265 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302266 dh.stopAlarmManager <- true
2267 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002268 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002269 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002270 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302271
Girish Gowdrae95687a2021-09-08 16:30:58 -07002272 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2273
mpagenko80622a52021-02-09 16:53:23 +00002274 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002275 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002276 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002277 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002278 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002279 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002280 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002281 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2282 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2283 // (even though it may also run into direct cancellation, a bit hard to verify here)
2284 // so don't set 'dh.upgradeCanceled = true' here!
2285 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2286 }
mpagenko38662d02021-08-11 09:45:19 +00002287 }
mpagenko80622a52021-02-09 16:53:23 +00002288
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002289 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002290 return nil
2291}
2292
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002293func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2294 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 +05302295
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002296 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002297 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002298 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002299 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002300 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002301 _ = dh.deviceReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling())
2302 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002303
mpagenkoa40e99a2020-11-17 13:50:39 +00002304 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2305 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2306 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2307 * disable/enable toggling here to allow traffic
2308 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2309 * like the py comment says:
2310 * # start by locking all the unis till mib sync and initial mib is downloaded
2311 * # this way we can capture the port down/up events when we are ready
2312 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302313
mpagenkoa40e99a2020-11-17 13:50:39 +00002314 // Init Uni Ports to Admin locked state
2315 // *** should generate UniLockStateDone event *****
2316 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002317 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002318 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002319 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002320 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002321 }
2322}
2323
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002324func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2325 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302326 /* Mib download procedure -
2327 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2328 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002329 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002330 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002331 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002332 return
2333 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002334 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302335 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002336 if pMibDlFsm.Is(mib.DlStDisabled) {
2337 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2338 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 +05302339 // maybe try a FSM reset and then again ... - TODO!!!
2340 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002341 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302342 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002343 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2344 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302345 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002346 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302347 //Begin MIB data download (running autonomously)
2348 }
2349 }
2350 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002351 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002352 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302353 // maybe try a FSM reset and then again ... - TODO!!!
2354 }
2355 /***** Mib download started */
2356 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002357 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302358 }
2359}
2360
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002361func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2362 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302363 //initiate DevStateUpdate
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002364 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002365 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002366 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002367 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2368 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2369 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2370 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002371 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002372 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002373 ConnStatus: voltha.ConnectStatus_REACHABLE,
2374 OperStatus: voltha.OperStatus_ACTIVE,
2375 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302376 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002377 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302378 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002379 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302380 }
2381 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002382 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002383 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302384 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002385 _ = dh.deviceReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002386
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002387 if !dh.GetCollectorIsRunning() {
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002388 // Start PM collector routine
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002389 go dh.StartCollector(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002390 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002391 if !dh.GetAlarmManagerIsRunning(ctx) {
2392 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002393 }
2394
Girish Gowdrae95687a2021-09-08 16:30:58 -07002395 // Start flow handler routines per UNI
2396 for _, uniPort := range dh.uniEntityMap {
2397 // only if this port was enabled for use by the operator at startup
2398 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2399 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2400 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2401 }
2402 }
2403 }
2404
Girish Gowdrae0140f02021-02-02 16:55:09 -08002405 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002406 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002407 // There is no way we should be landing here, but if we do then
2408 // there is nothing much we can do about this other than log error
2409 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2410 }
2411
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002412 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002413
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002414 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002415 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002416 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002417 return
2418 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002419 pDevEntry.MutexPersOnuConfig.RLock()
2420 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2421 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002422 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002423 log.Fields{"device-id": dh.DeviceID})
2424 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002425 // reconcilement will be continued after ani config is done
2426 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002427 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002428 // *** should generate UniUnlockStateDone event *****
2429 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002430 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002431 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002432 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002433 dh.runUniLockFsm(ctx, false)
2434 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302435 }
2436}
2437
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002438func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2439 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302440
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002441 if !dh.IsReconciling() {
2442 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002443 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002444 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2445 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002446 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002447 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002448 return
2449 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002450 pDevEntry.MutexPersOnuConfig.Lock()
2451 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2452 pDevEntry.MutexPersOnuConfig.Unlock()
2453 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002454 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002455 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002456 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302457 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002458 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 +00002459 log.Fields{"device-id": dh.DeviceID})
2460 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002461 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302462 }
2463}
2464
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002465func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002466 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002467 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002468
mpagenko44bd8362021-11-15 11:40:05 +00002469 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002470 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002471 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002472 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002473 OperStatus: voltha.OperStatus_UNKNOWN,
2474 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002475 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002476 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002477 }
2478
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002479 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002480 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002481 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002482
2483 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002484 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002485
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002486 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002487 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002488 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002489 return
2490 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002491 pDevEntry.MutexPersOnuConfig.Lock()
2492 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2493 pDevEntry.MutexPersOnuConfig.Unlock()
2494 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002495 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002496 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002497 }
mpagenko900ee4b2020-10-12 11:56:34 +00002498}
2499
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002500func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002501 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002502 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002503 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002504 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002505 ConnStatus: voltha.ConnectStatus_REACHABLE,
2506 OperStatus: voltha.OperStatus_ACTIVE,
2507 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002508 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002509 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002510 }
2511
dbainbri4d3a0dc2020-12-02 00:33:42 +00002512 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002513 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002514 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002515 _ = dh.deviceReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002516
2517 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002518 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002519
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002520 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002521 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002522 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002523 return
2524 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002525 pDevEntry.MutexPersOnuConfig.Lock()
2526 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2527 pDevEntry.MutexPersOnuConfig.Unlock()
2528 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002529 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002530 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002531 }
mpagenko900ee4b2020-10-12 11:56:34 +00002532}
2533
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002534func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2535 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2536 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002537 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002538 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002539 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002540 OperStatus: voltha.OperStatus_FAILED,
2541 }); err != nil {
2542 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2543 }
2544}
2545
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002546func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2547 if devEvent == cmn.OmciAniConfigDone {
2548 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002549 // attention: the device reason update is done based on ONU-UNI-Port related activity
2550 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002551 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002552 // 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 +00002553 _ = dh.deviceReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302554 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002555 if dh.IsReconciling() {
2556 go dh.ReconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002557 }
2558 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002559 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002560 // attention: the device reason update is done based on ONU-UNI-Port related activity
2561 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002562 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002563 // 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 +00002564 _ = dh.deviceReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002565 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002566 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302567}
2568
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002569func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002570 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002571 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302572 // attention: the device reason update is done based on ONU-UNI-Port related activity
2573 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302574
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002575 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2576 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002577 // which may be the case from some previous actvity on another UNI Port of the ONU
2578 // or even some previous flow add activity on the same port
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002579 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling())
2580 if dh.IsReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002581 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002582 }
2583 }
2584 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002585 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002586 //not relevant for reconcile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002587 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002588 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302589 }
mpagenkof1fc3862021-02-16 10:09:52 +00002590
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002591 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002592 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002593 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002594 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002595 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002596 }
2597 } else {
2598 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002599 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002600 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302601}
2602
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002603//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
2604func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302605 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002606 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002607 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002608 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002609 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002610 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002611 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002612 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002613 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002614 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002615 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002616 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002617 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002618 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002619 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002620 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002621 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002622 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002623 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002624 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002625 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002626 case cmn.UniEnableStateFailed:
2627 {
2628 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2629 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002630 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002631 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002632 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002633 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002634 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002635 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002636 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002637 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002638 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002639 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002640 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002641 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002642 default:
2643 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002644 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002645 }
2646 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002647}
2648
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002649func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002650 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002651 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302652 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002653 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002654 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002655 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302656 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002657 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002658 if pUniPort == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002659 logger.Warnw(ctx, "OnuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002660 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002661 //store UniPort with the System-PortNumber key
2662 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002663 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002664 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002665 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
2666 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002667 } //error logging already within UniPort method
2668 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002669 logger.Debugw(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002670 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002671 }
2672 }
2673}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002674
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002675func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2676 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002677 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002678 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002679 return
2680 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002681 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002682 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002683 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2684 for _, mgmtEntityID := range pptpInstKeys {
2685 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002686 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002687 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2688 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002689 }
2690 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002691 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002692 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002693 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002694 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2695 for _, mgmtEntityID := range veipInstKeys {
2696 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002697 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002698 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2699 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002700 }
2701 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002702 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002703 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002704 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002705 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2706 for _, mgmtEntityID := range potsInstKeys {
2707 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002708 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002709 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2710 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002711 }
2712 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002713 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002714 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002715 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002716 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002717 return
2718 }
2719
2720 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2721 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2722 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
2723 for i := 0; i < int(uniCnt); i++ {
2724 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
2725 dh.stopFlowMonitoringRoutine[i] = make(chan bool)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002726 }
2727}
2728
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002729// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2730func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002731 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302732 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002733 // with following remark:
2734 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2735 // # load on the core
2736
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002737 // 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 +00002738
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002739 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002740 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002741 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2742 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2743 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2744 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002745 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002746 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002747 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002748 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002749 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002750 PortNo: port.PortNo,
2751 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002752 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002753 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 -04002754 }
2755 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002756 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002757 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002758 }
mpagenko3af1f032020-06-10 08:53:41 +00002759 }
2760 }
2761}
2762
2763// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002764func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2765 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002766 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2767 for uniNo, uniPort := range dh.uniEntityMap {
2768 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002769
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002770 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2771 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2772 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2773 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002774 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002775 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002776 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002777 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002778 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002779 PortNo: port.PortNo,
2780 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002781 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002782 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 -04002783 }
2784 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002785 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002786 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002787 }
2788
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002789 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002790 }
2791}
2792
2793// ONU_Active/Inactive announcement on system KAFKA bus
2794// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002795func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002796 var de voltha.DeviceEvent
2797 eventContext := make(map[string]string)
2798 //Populating event context
2799 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002800 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002801 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002802 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302803 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002804 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 +00002805 }
2806 oltSerialNumber := parentDevice.SerialNumber
2807
2808 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2809 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2810 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302811 eventContext["olt-serial-number"] = oltSerialNumber
2812 eventContext["device-id"] = aDeviceID
2813 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002814 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002815 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2816 deviceEntry.MutexPersOnuConfig.RLock()
2817 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2818 deviceEntry.MutexPersOnuConfig.RUnlock()
2819 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
2820 deviceEntry.MutexPersOnuConfig.RLock()
2821 eventContext["vendor"] = deviceEntry.SOnuPersistentData.PersVendorID
2822 deviceEntry.MutexPersOnuConfig.RUnlock()
2823 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002824 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2825 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2826 } else {
2827 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2828 log.Fields{"device-id": aDeviceID})
2829 return
2830 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002831
2832 /* Populating device event body */
2833 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302834 de.ResourceId = aDeviceID
2835 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002836 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2837 de.Description = fmt.Sprintf("%s Event - %s - %s",
2838 cEventObjectType, cOnuActivatedEvent, "Raised")
2839 } else {
2840 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2841 de.Description = fmt.Sprintf("%s Event - %s - %s",
2842 cEventObjectType, cOnuActivatedEvent, "Cleared")
2843 }
2844 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002845 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2846 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302847 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002848 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002849 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302850 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002851}
2852
Himani Chawla4d908332020-08-31 12:30:20 +05302853// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002854func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2855 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002856 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302857 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002858 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002859 sFsmName = "LockStateFSM"
2860 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002861 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002862 sFsmName = "UnLockStateFSM"
2863 }
mpagenko3af1f032020-06-10 08:53:41 +00002864
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002865 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002866 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002867 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002868 return
2869 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002870 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002871 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302872 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002873 dh.pLockStateFsm = pLSFsm
2874 } else {
2875 dh.pUnlockStateFsm = pLSFsm
2876 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002877 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002878 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002879 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002880 }
2881}
2882
2883// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002884func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002885 /* Uni Port lock/unlock procedure -
2886 ***** should run via 'adminDone' state and generate the argument requested event *****
2887 */
2888 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302889 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002890 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002891 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2892 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002893 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2894 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002895 }
2896 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002897 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002898 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2899 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002900 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2901 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002902 }
2903 }
2904 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002905 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2906 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002907 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002908 // maybe try a FSM reset and then again ... - TODO!!!
2909 } else {
2910 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002911 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002912 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002913 }
2914 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002915 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002916 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002917 // maybe try a FSM reset and then again ... - TODO!!!
2918 }
2919 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002920 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002921 // maybe try a FSM reset and then again ... - TODO!!!
2922 }
2923}
2924
mpagenko80622a52021-02-09 16:53:23 +00002925// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00002926// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002927func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002928 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002929 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002930 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002931 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002932 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002933 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002934 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002935 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002936 sFsmName, chUpgradeFsm)
2937 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002938 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00002939 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002940 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
2941 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
mpagenko80622a52021-02-09 16:53:23 +00002942 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2943 // maybe try a FSM reset and then again ... - TODO!!!
2944 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2945 }
mpagenko59862f02021-10-11 08:53:18 +00002946 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00002947 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2948 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00002949 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2950 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002951 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002952 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002953 } else {
2954 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002955 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002956 // maybe try a FSM reset and then again ... - TODO!!!
2957 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2958 }
2959 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002960 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002961 // maybe try a FSM reset and then again ... - TODO!!!
2962 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2963 }
2964 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002965 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002966 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2967 }
2968 return nil
2969}
2970
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002971// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
2972func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002973 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002974 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002975 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00002976 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2977 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00002978 dh.pLastUpgradeImageState = apImageState
2979 dh.lockUpgradeFsm.Unlock()
2980 //signal upgradeFsm removed using non-blocking channel send
2981 select {
2982 case dh.upgradeFsmChan <- struct{}{}:
2983 default:
2984 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002985 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00002986 }
mpagenko80622a52021-02-09 16:53:23 +00002987}
2988
mpagenko15ff4a52021-03-02 10:09:20 +00002989// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2990func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002991 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00002992 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002993 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002994 return
2995 }
2996
2997 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00002998 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00002999 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003000 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3001 dh.lockUpgradeFsm.RUnlock()
3002 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3003 return
3004 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003005 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003006 if pUpgradeStatemachine != nil {
3007 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3008 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003009 UpgradeState := pUpgradeStatemachine.Current()
3010 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3011 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3012 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003013 // 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 +00003014 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003015 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3016 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003017 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003018 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003019 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003020 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3021 dh.upgradeCanceled = true
3022 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3023 }
mpagenko15ff4a52021-03-02 10:09:20 +00003024 return
3025 }
mpagenko59862f02021-10-11 08:53:18 +00003026 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003027 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3028 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003029 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003030 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
mpagenko1f8e8822021-06-25 14:10:21 +00003031 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
3032 return
3033 }
3034 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003035 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003036 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003037 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3038 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
mpagenko1f8e8822021-06-25 14:10:21 +00003039 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
3040 return
3041 }
3042 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003043 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003044 }
3045 } else {
3046 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 +00003047 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003048 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3049 dh.upgradeCanceled = true
3050 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3051 }
mpagenko1f8e8822021-06-25 14:10:21 +00003052 }
mpagenko15ff4a52021-03-02 10:09:20 +00003053 return
3054 }
mpagenko59862f02021-10-11 08:53:18 +00003055 dh.lockUpgradeFsm.RUnlock()
3056 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3057 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003058 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3059 dh.upgradeCanceled = true
3060 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3061 }
mpagenko59862f02021-10-11 08:53:18 +00003062 return
3063 }
3064 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3065 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3066 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3067 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3068 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3069 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3070 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003071 }
mpagenko15ff4a52021-03-02 10:09:20 +00003072 }
3073 }
3074 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003075 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003076 }
mpagenko59862f02021-10-11 08:53:18 +00003077 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003078}
3079
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003080//SetBackend provides a DB backend for the specified path on the existing KV client
3081func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003082
3083 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003084 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003085 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003086 kvbackend := &db.Backend{
3087 Client: dh.pOpenOnuAc.kvClient,
3088 StoreType: dh.pOpenOnuAc.KVStoreType,
3089 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003090 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003091 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3092 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003093
mpagenkoaf801632020-07-03 10:00:42 +00003094 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003095}
khenaidoo7d3c5582021-08-11 18:09:44 -04003096func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05303097 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003098
mpagenkodff5dda2020-08-28 11:52:01 +00003099 for _, field := range flow.GetOfbFields(apFlowItem) {
3100 switch field.Type {
3101 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3102 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003103 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003104 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3105 }
mpagenko01e726e2020-10-23 09:45:29 +00003106 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003107 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3108 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303109 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003110 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303111 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3112 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003113 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3114 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003115 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003116 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303117 return
mpagenkodff5dda2020-08-28 11:52:01 +00003118 }
3119 }
mpagenko01e726e2020-10-23 09:45:29 +00003120 */
mpagenkodff5dda2020-08-28 11:52:01 +00003121 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3122 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303123 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003124 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303125 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003126 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303127 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003128 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003129 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303130 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003131 }
3132 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3133 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303134 *loAddPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003135 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003136 "PCP": loAddPcp})
3137 }
3138 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3139 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003140 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003141 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3142 }
3143 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3144 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003145 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003146 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3147 }
3148 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3149 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003150 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003151 "IPv4-DST": field.GetIpv4Dst()})
3152 }
3153 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3154 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003155 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003156 "IPv4-SRC": field.GetIpv4Src()})
3157 }
3158 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3159 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003160 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003161 "Metadata": field.GetTableMetadata()})
3162 }
3163 /*
3164 default:
3165 {
3166 //all other entires ignored
3167 }
3168 */
3169 }
3170 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303171}
mpagenkodff5dda2020-08-28 11:52:01 +00003172
khenaidoo7d3c5582021-08-11 18:09:44 -04003173func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003174 for _, action := range flow.GetActions(apFlowItem) {
3175 switch action.Type {
3176 /* not used:
3177 case of.OfpActionType_OFPAT_OUTPUT:
3178 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003179 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003180 "Output": action.GetOutput()})
3181 }
3182 */
3183 case of.OfpActionType_OFPAT_PUSH_VLAN:
3184 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003185 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003186 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3187 }
3188 case of.OfpActionType_OFPAT_SET_FIELD:
3189 {
3190 pActionSetField := action.GetSetField()
3191 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003192 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003193 "OxcmClass": pActionSetField.Field.OxmClass})
3194 }
3195 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303196 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003197 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303198 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003199 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303200 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003201 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303202 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003203 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003204 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003205 "Type": pActionSetField.Field.GetOfbField().Type})
3206 }
3207 }
3208 /*
3209 default:
3210 {
3211 //all other entires ignored
3212 }
3213 */
3214 }
3215 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303216}
3217
3218//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003219func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003220 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303221 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3222 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
3223 var loAddPcp, loSetPcp uint8
3224 var loIPProto uint32
3225 /* the TechProfileId is part of the flow Metadata - compare also comment within
3226 * OLT-Adapter:openolt_flowmgr.go
3227 * Metadata 8 bytes:
3228 * Most Significant 2 Bytes = Inner VLAN
3229 * Next 2 Bytes = Tech Profile ID(TPID)
3230 * Least Significant 4 Bytes = Port ID
3231 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3232 * subscriber related flows.
3233 */
3234
dbainbri4d3a0dc2020-12-02 00:33:42 +00003235 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303236 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003237 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003238 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003239 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303240 }
mpagenko551a4d42020-12-08 18:09:20 +00003241 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003242 loCookie := apFlowItem.GetCookie()
3243 loCookieSlice := []uint64{loCookie}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003244 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003245 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05303246
dbainbri4d3a0dc2020-12-02 00:33:42 +00003247 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003248 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303249 if loIPProto == 2 {
3250 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3251 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003252 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003253 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303254 return nil
3255 }
mpagenko01e726e2020-10-23 09:45:29 +00003256 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003257 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003258
3259 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003260 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003261 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003262 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3263 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3264 //TODO!!: Use DeviceId within the error response to rwCore
3265 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003266 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003267 }
3268 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003269 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003270 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3271 } else {
3272 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3273 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3274 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303275 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003276 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003277 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003278 }
mpagenko9a304ea2020-12-16 15:54:01 +00003279
khenaidoo42dcdfd2021-10-19 17:34:12 -04003280 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003281 if apFlowMetaData != nil {
3282 meter = apFlowMetaData.Meters[0]
3283 }
mpagenkobc4170a2021-08-17 16:42:10 +00003284 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3285 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3286 // when different rules are requested concurrently for the same uni
3287 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3288 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3289 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003290 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3291 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003292 //SetUniFlowParams() may block on some rule that is suspended-to-add
3293 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003294 // Also the error is returned to caller via response channel
3295 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
3296 loMatchVlan, loSetVlan, loSetPcp, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003297 dh.lockVlanConfig.RUnlock()
3298 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003299 return
mpagenkodff5dda2020-08-28 11:52:01 +00003300 }
mpagenkobc4170a2021-08-17 16:42:10 +00003301 dh.lockVlanConfig.RUnlock()
3302 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003303 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003304 loMatchVlan, loSetVlan, loSetPcp, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003305 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003306 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003307 if err != nil {
3308 *respChan <- err
3309 }
mpagenko01e726e2020-10-23 09:45:29 +00003310}
3311
3312//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003313func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003314 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3315 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3316 //no extra check is done on the rule parameters
3317 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3318 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3319 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3320 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003321 // - 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 +00003322 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003323 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003324
3325 /* TT related temporary workaround - should not be needed anymore
3326 for _, field := range flow.GetOfbFields(apFlowItem) {
3327 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3328 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003329 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003330 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3331 if loIPProto == 2 {
3332 // 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 +00003333 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003334 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003335 return nil
3336 }
3337 }
3338 } //for all OfbFields
3339 */
3340
mpagenko9a304ea2020-12-16 15:54:01 +00003341 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003342 dh.lockVlanConfig.RLock()
3343 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003344 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3345 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003346 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3347 return
mpagenko01e726e2020-10-23 09:45:29 +00003348 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003349 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003350 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003351 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003352 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003353 // Push response on the response channel
3354 if respChan != nil {
3355 // 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
3356 select {
3357 case *respChan <- nil:
3358 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3359 default:
3360 }
3361 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003362 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003363}
3364
Himani Chawla26e555c2020-08-31 12:30:20 +05303365// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003366// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003367// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003368func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003369 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 +00003370 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003371
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003372 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003373 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003374 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3375 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003376 }
3377
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003378 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3379 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003380 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003381 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003382 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3383 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003384 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3385 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003386 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003387 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3388 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003389 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003390 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003391 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303392 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003393 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003394 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3395 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003396 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003397 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003398 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3399 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003400 }
3401 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003402 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003403 "device-id": dh.DeviceID})
3404 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003405 }
3406 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003407 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003408 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3409 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003410 }
3411 return nil
3412}
3413
mpagenkofc4f56e2020-11-04 17:17:49 +00003414//VerifyVlanConfigRequest checks on existence of a given uniPort
3415// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003416func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003417 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003418 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003419 for _, uniPort := range dh.uniEntityMap {
3420 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003421 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003422 pCurrentUniPort = uniPort
3423 break //found - end search loop
3424 }
3425 }
3426 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003427 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003428 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003429 return
3430 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003431 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003432}
3433
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003434//VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
3435func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003436 //TODO!! verify and start pending flow configuration
3437 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3438 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003439
3440 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003441 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003442 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003443 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003444 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003445 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003446 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003447 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003448 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3449 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003450 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003451 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003452 } else {
3453 /***** UniVlanConfigFsm continued */
3454 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003455 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3456 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003457 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003458 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3459 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003460 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003461 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003462 } else {
3463 /***** UniVlanConfigFsm continued */
3464 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003465 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3466 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003467 }
mpagenkodff5dda2020-08-28 11:52:01 +00003468 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003469 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003470 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3471 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003472 }
3473 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003474 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 +00003475 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3476 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003477 }
3478 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003479 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003480 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003481 }
mpagenkof1fc3862021-02-16 10:09:52 +00003482 } else {
3483 dh.lockVlanConfig.RUnlock()
3484 }
mpagenkodff5dda2020-08-28 11:52:01 +00003485}
3486
3487//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3488// 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 +00003489func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003490 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003491 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003492 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003493 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003494 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003495 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003496}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003497
mpagenkof1fc3862021-02-16 10:09:52 +00003498//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003499func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003500 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3501 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3502 // obviously then parallel processing on the cancel must be avoided
3503 // deadline context to ensure completion of background routines waited for
3504 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3505 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3506 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3507
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003508 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003509 var wg sync.WaitGroup
3510 wg.Add(1) // for the 1 go routine to finish
3511
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003512 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003513 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3514
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003515 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003516}
3517
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003518//StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003519//available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003520func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3521 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003522
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003523 if dh.IsReconciling() {
3524 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003525 return nil
3526 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003527 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003528
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003529 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003530 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003531 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3532 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003533 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003534 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003535
mpagenkof1fc3862021-02-16 10:09:52 +00003536 if aWriteToKvStore {
3537 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3538 }
3539 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003540}
3541
dbainbri4d3a0dc2020-12-02 00:33:42 +00003542func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003543 defer cancel() //ensure termination of context (may be pro forma)
3544 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003545 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003546 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003547}
3548
dbainbri4d3a0dc2020-12-02 00:33:42 +00003549func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003550
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003551 dh.SetDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003552 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003553 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003554 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003555 DeviceId: dh.DeviceID,
3556 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003557 }); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003558 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003559 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003560 return err
3561 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003562 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", cmn.DeviceReasonMap[deviceReason], dh.DeviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003563 return nil
3564 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003565 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 +00003566 return nil
3567}
3568
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003569func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3570 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003571 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003572 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3573 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003574 }
mpagenkof1fc3862021-02-16 10:09:52 +00003575 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003576}
3577
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003578// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003579// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003580func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3581 dh.lockDevice.RLock()
3582 defer dh.lockDevice.RUnlock()
3583 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003584 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003585 }
3586 return 0, errors.New("error-fetching-uni-port")
3587}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003588
3589// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003590func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3591 var errorsList []error
3592 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 -08003593
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003594 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3595 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3596 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3597
3598 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3599 // successfully.
3600 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3601 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3602 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003603 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 -08003604 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003605 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003606 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003607 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003608}
3609
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003610func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3611 var err error
3612 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003613 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003614
3615 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003616 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003617 errorsList = append(errorsList, err)
3618 }
3619 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003620 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003621
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003622 return errorsList
3623}
3624
3625func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3626 var err error
3627 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003628 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003629 // Check if group metric related config is updated
3630 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003631 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3632 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3633 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003634
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003635 if ok && m.Frequency != v.GroupFreq {
3636 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003637 errorsList = append(errorsList, err)
3638 }
3639 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003640 if ok && m.Enabled != v.Enabled {
3641 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003642 errorsList = append(errorsList, err)
3643 }
3644 }
3645 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003646 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003647 return errorsList
3648}
3649
3650func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3651 var err error
3652 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003653 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003654 // Check if standalone metric related config is updated
3655 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003656 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3657 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3658 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003659
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003660 if ok && m.Frequency != v.SampleFreq {
3661 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003662 errorsList = append(errorsList, err)
3663 }
3664 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003665 if ok && m.Enabled != v.Enabled {
3666 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003667 errorsList = append(errorsList, err)
3668 }
3669 }
3670 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003671 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003672 return errorsList
3673}
3674
3675// nolint: gocyclo
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003676func (dh *deviceHandler) StartCollector(ctx context.Context) {
Girish Gowdrae09a6202021-01-12 18:10:59 -08003677 logger.Debugf(ctx, "startingCollector")
3678
3679 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003680 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303681 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003682 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003683 // Initialize the next metric collection time.
3684 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3685 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003686 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003687 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003688 for {
3689 select {
3690 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003691 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003692 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003693 // Stop the L2 PM FSM
3694 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003695 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3696 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3697 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003698 }
3699 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003700 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003701 }
3702 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003703 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3704 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003705 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003706 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3707 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003708 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003709
Girish Gowdrae09a6202021-01-12 18:10:59 -08003710 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003711 case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3712 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3713 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3714 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3715 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003716 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003717 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003718 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003719 } else {
3720 if dh.pmConfigs.Grouped { // metrics are managed as a group
3721 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003722 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003723
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003724 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3725 // 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 -08003726 // 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 +00003727 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3728 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003729 }
3730 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003731 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3732 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3733 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3734 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003735 }
3736 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003737 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003738
3739 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003740 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3741 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3742 // 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 -08003743 // 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 +00003744 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3745 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003746 }
3747 }
3748 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003749 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3750 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3751 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3752 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003753 }
3754 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003755 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003756 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003757 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003758 } */
3759 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003760 }
3761 }
3762}
kesavandfdf77632021-01-26 23:40:33 -05003763
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003764func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003765
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003766 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3767 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003768}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003769
Himani Chawla43f95ff2021-06-03 00:24:12 +05303770func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3771 if dh.pOnuMetricsMgr == nil {
3772 return &extension.SingleGetValueResponse{
3773 Response: &extension.GetValueResponse{
3774 Status: extension.GetValueResponse_ERROR,
3775 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3776 },
3777 }
3778 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303779 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303780 return resp
3781}
3782
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003783func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3784 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003785 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003786 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003787 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003788}
3789
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003790func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003791 var pAdapterFsm *cmn.AdapterFsm
3792 //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 +00003793 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003794 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003795 {
mpagenkofbf577d2021-10-12 11:44:33 +00003796 if dh.pOnuOmciDevice != nil {
3797 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3798 } else {
3799 return true //FSM not active - so there is no activity on omci
3800 }
mpagenkof1fc3862021-02-16 10:09:52 +00003801 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003802 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003803 {
mpagenkofbf577d2021-10-12 11:44:33 +00003804 if dh.pOnuOmciDevice != nil {
3805 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3806 } else {
3807 return true //FSM not active - so there is no activity on omci
3808 }
mpagenkof1fc3862021-02-16 10:09:52 +00003809 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003810 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003811 {
mpagenkofbf577d2021-10-12 11:44:33 +00003812 if dh.pLockStateFsm != nil {
3813 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3814 } else {
3815 return true //FSM not active - so there is no activity on omci
3816 }
mpagenkof1fc3862021-02-16 10:09:52 +00003817 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003818 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003819 {
mpagenkofbf577d2021-10-12 11:44:33 +00003820 if dh.pUnlockStateFsm != nil {
3821 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3822 } else {
3823 return true //FSM not active - so there is no activity on omci
3824 }
mpagenkof1fc3862021-02-16 10:09:52 +00003825 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003826 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003827 {
mpagenkofbf577d2021-10-12 11:44:33 +00003828 if dh.pOnuMetricsMgr != nil {
3829 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003830 } else {
3831 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003832 }
3833 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003834 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003835 {
3836 dh.lockUpgradeFsm.RLock()
3837 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003838 if dh.pOnuUpradeFsm != nil {
3839 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3840 } else {
3841 return true //FSM not active - so there is no activity on omci
3842 }
mpagenko80622a52021-02-09 16:53:23 +00003843 }
mpagenkof1fc3862021-02-16 10:09:52 +00003844 default:
3845 {
3846 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003847 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003848 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003849 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003850 }
mpagenkofbf577d2021-10-12 11:44:33 +00003851 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3852 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3853 }
3854 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003855}
3856
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003857func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3858 for _, v := range dh.pOnuTP.PAniConfigFsm {
3859 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003860 return false
3861 }
3862 }
3863 return true
3864}
3865
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003866func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003867 dh.lockVlanConfig.RLock()
3868 defer dh.lockVlanConfig.RUnlock()
3869 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003870 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003871 return false
3872 }
3873 }
3874 return true //FSM not active - so there is no activity on omci
3875}
3876
3877func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3878 dh.lockVlanConfig.RLock()
3879 defer dh.lockVlanConfig.RUnlock()
3880 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003881 if v.PAdaptFsm.PFsm != nil {
3882 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003883 return true //there is at least one VLAN FSM with some active configuration
3884 }
3885 }
3886 }
3887 return false //there is no VLAN FSM with some active configuration
3888}
3889
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003890func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003891 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3892 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3893 return false
3894 }
3895 }
3896 // a further check is done to identify, if at least some data traffic related configuration exists
3897 // 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])
3898 return dh.checkUserServiceExists(ctx)
3899}
3900
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003901func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003902 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3903 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003904 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003905 // TODO: fatal error reset ONU, delete deviceHandler!
3906 return
3907 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003908 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
3909 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003910}
3911
3912func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3913 dh.mutexCollectorFlag.Lock()
3914 dh.collectorIsRunning = flagValue
3915 dh.mutexCollectorFlag.Unlock()
3916}
3917
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003918func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003919 dh.mutexCollectorFlag.RLock()
3920 flagValue := dh.collectorIsRunning
3921 dh.mutexCollectorFlag.RUnlock()
3922 return flagValue
3923}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303924
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303925func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3926 dh.mutextAlarmManagerFlag.Lock()
3927 dh.alarmManagerIsRunning = flagValue
3928 dh.mutextAlarmManagerFlag.Unlock()
3929}
3930
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003931func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303932 dh.mutextAlarmManagerFlag.RLock()
3933 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303934 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303935 dh.mutextAlarmManagerFlag.RUnlock()
3936 return flagValue
3937}
3938
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003939func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303940 logger.Debugf(ctx, "startingAlarmManager")
3941
3942 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003943 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303944 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303945 if stop := <-dh.stopAlarmManager; stop {
3946 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303947 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303948 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003949 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
3950 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05303951 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303952 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003953 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
3954 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05303955 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303956 }
3957}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003958
Girish Gowdrae95687a2021-09-08 16:30:58 -07003959func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
3960 dh.mutexFlowMonitoringRoutineFlag.Lock()
3961 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
3962 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"flag": flag})
3963 dh.isFlowMonitoringRoutineActive[uniID] = flag
3964}
3965
3966func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
3967 dh.mutexFlowMonitoringRoutineFlag.RLock()
3968 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
3969 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
3970 log.Fields{"isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
3971 return dh.isFlowMonitoringRoutineActive[uniID]
3972}
3973
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003974func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
3975 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003976
Maninder7961d722021-06-16 22:10:28 +05303977 connectStatus := voltha.ConnectStatus_UNREACHABLE
3978 operState := voltha.OperStatus_UNKNOWN
3979
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003980 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003981 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003982 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00003983 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003984 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003985 case success := <-dh.chReconcilingFinished:
3986 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003987 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05303988 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003989 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05303990 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003991 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05303992 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003993 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
3994 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05303995 operState = voltha.OperStatus_ACTIVE
3996 } else {
3997 operState = voltha.OperStatus_ACTIVATING
3998 }
3999 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004000 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4001 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4002 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304003 operState = voltha.OperStatus_DISCOVERED
4004 }
4005
4006 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304007 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004008 logger.Debugw(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004009 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004010 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004011 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004012 ConnStatus: connectStatus,
4013 OperStatus: operState,
4014 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304015 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004016 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304017 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004018 } else {
Maninderb5187552021-03-23 22:23:42 +05304019 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004020 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304021
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004022 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304023 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004024 log.Fields{"device-id": dh.DeviceID})
4025 } else if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninder7961d722021-06-16 22:10:28 +05304026 connectStatus = voltha.ConnectStatus_REACHABLE
4027 }
4028
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004029 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004030 }
mpagenko101ac942021-11-16 15:01:29 +00004031 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004032 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004033 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304034
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004035 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304036 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004037 log.Fields{"device-id": dh.DeviceID})
4038 } else if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninder7961d722021-06-16 22:10:28 +05304039 connectStatus = voltha.ConnectStatus_REACHABLE
4040 }
4041
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004042 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304043
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004044 }
4045 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004046 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004047 dh.mutexReconcilingFlag.Unlock()
4048 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004049 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004050 dh.mutexReconcilingFlag.Lock()
4051 if skipOnuConfig {
4052 dh.reconciling = cSkipOnuConfigReconciling
4053 } else {
4054 dh.reconciling = cOnuConfigReconciling
4055 }
4056 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004057}
4058
mpagenko101ac942021-11-16 15:01:29 +00004059func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004060 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
4061 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004062 dh.sendChReconcileFinished(success)
4063 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4064 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4065 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004066 } else {
mpagenko101ac942021-11-16 15:01:29 +00004067 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004068 }
4069}
4070
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004071func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004072 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004073 defer dh.mutexReconcilingFlag.RUnlock()
4074 return dh.reconciling != cNoReconciling
4075}
4076
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004077func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004078 dh.mutexReconcilingFlag.RLock()
4079 defer dh.mutexReconcilingFlag.RUnlock()
4080 return dh.reconciling == cSkipOnuConfigReconciling
4081}
4082
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004083func (dh *deviceHandler) SetDeviceReason(value uint8) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004084 dh.mutexDeviceReason.Lock()
4085 dh.deviceReason = value
4086 dh.mutexDeviceReason.Unlock()
4087}
4088
4089func (dh *deviceHandler) getDeviceReason() uint8 {
4090 dh.mutexDeviceReason.RLock()
4091 value := dh.deviceReason
4092 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004093 return value
4094}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004095
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004096func (dh *deviceHandler) GetDeviceReasonString() string {
4097 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004098}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004099
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004100func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004101 dh.mutexReadyForOmciConfig.Lock()
4102 dh.readyForOmciConfig = flagValue
4103 dh.mutexReadyForOmciConfig.Unlock()
4104}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004105func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004106 dh.mutexReadyForOmciConfig.RLock()
4107 flagValue := dh.readyForOmciConfig
4108 dh.mutexReadyForOmciConfig.RUnlock()
4109 return flagValue
4110}
Maninder7961d722021-06-16 22:10:28 +05304111
4112func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
4113 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
4114 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004115 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304116 }
4117
4118 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004119 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004120 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004121 ConnStatus: connectStatus,
4122 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4123 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304124 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004125 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304126 }
4127}
khenaidoo7d3c5582021-08-11 18:09:44 -04004128
4129/*
4130Helper functions to communicate with Core
4131*/
4132
4133func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4134 cClient, err := dh.coreClient.GetCoreServiceClient()
4135 if err != nil || cClient == nil {
4136 return nil, err
4137 }
4138 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4139 defer cancel()
4140 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4141 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4142}
4143
khenaidoo42dcdfd2021-10-19 17:34:12 -04004144func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004145 cClient, err := dh.coreClient.GetCoreServiceClient()
4146 if err != nil || cClient == nil {
4147 return err
4148 }
4149 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4150 defer cancel()
4151 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
4152 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-state": deviceStateFilter, "error": err})
4153 return err
4154}
4155
4156func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4157 cClient, err := dh.coreClient.GetCoreServiceClient()
4158 if err != nil || cClient == nil {
4159 return err
4160 }
4161 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4162 defer cancel()
4163 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
4164 logger.Debugw(subCtx, "pmconfig-updated-in-core", log.Fields{"pm-configs": pmConfigs, "error": err})
4165 return err
4166}
4167
4168func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4169 cClient, err := dh.coreClient.GetCoreServiceClient()
4170 if err != nil || cClient == nil {
4171 return err
4172 }
4173 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4174 defer cancel()
4175 _, err = cClient.DeviceUpdate(subCtx, device)
4176 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4177 return err
4178}
4179
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004180func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004181 cClient, err := dh.coreClient.GetCoreServiceClient()
4182 if err != nil || cClient == nil {
4183 return err
4184 }
4185 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4186 defer cancel()
4187 _, err = cClient.PortCreated(subCtx, port)
4188 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4189 return err
4190}
4191
khenaidoo42dcdfd2021-10-19 17:34:12 -04004192func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004193 cClient, err := dh.coreClient.GetCoreServiceClient()
4194 if err != nil || cClient == nil {
4195 return err
4196 }
4197 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4198 defer cancel()
4199 _, err = cClient.PortStateUpdate(subCtx, portState)
4200 logger.Debugw(subCtx, "port-state-updated-in-core", log.Fields{"port-state": portState, "error": err})
4201 return err
4202}
4203
khenaidoo42dcdfd2021-10-19 17:34:12 -04004204func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004205 cClient, err := dh.coreClient.GetCoreServiceClient()
4206 if err != nil || cClient == nil {
4207 return err
4208 }
4209 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4210 defer cancel()
4211 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
4212 logger.Debugw(subCtx, "device-reason-updated-in-core", log.Fields{"reason": reason, "error": err})
4213 return err
4214}
4215
4216/*
4217Helper functions to communicate with parent adapter
4218*/
4219
4220func (dh *deviceHandler) getTechProfileInstanceFromParentAdapter(ctx context.Context, parentEndpoint string,
khenaidoo42dcdfd2021-10-19 17:34:12 -04004221 request *ia.TechProfileInstanceRequestMessage) (*ia.TechProfileDownloadMessage, error) {
khenaidoo7d3c5582021-08-11 18:09:44 -04004222 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4223 if err != nil || pgClient == nil {
4224 return nil, err
4225 }
4226 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4227 defer cancel()
4228 logger.Debugw(subCtx, "get-tech-profile-instance", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4229 return pgClient.GetTechProfileInstance(subCtx, request)
4230}
4231
Girish Gowdrae95687a2021-09-08 16:30:58 -07004232// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4233// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4234func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4235 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4236 dh.setFlowMonitoringIsRunning(uniID, true)
4237 for {
4238 select {
4239 // block on the channel to receive an incoming flow
4240 // process the flow completely before proceeding to handle the next flow
4241 case flowCb := <-dh.flowCbChan[uniID]:
4242 startTime := time.Now()
4243 logger.Debugw(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
4244 respChan := make(chan error)
4245 if flowCb.addFlow {
4246 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4247 } else {
4248 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4249 }
4250 // Block on response and tunnel it back to the caller
4251 *flowCb.respChan <- <-respChan
4252 logger.Debugw(flowCb.ctx, "serial-flow-processor--end",
4253 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4254 case <-dh.stopFlowMonitoringRoutine[uniID]:
4255 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4256 dh.setFlowMonitoringIsRunning(uniID, false)
4257 return
4258 }
4259 }
4260}
4261
khenaidoo42dcdfd2021-10-19 17:34:12 -04004262func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004263 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4264 if err != nil || pgClient == nil {
4265 return err
4266 }
4267 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4268 defer cancel()
4269 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4270 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4271 if err != nil {
4272 logger.Errorw(ctx, "omci-failure", log.Fields{"request": request, "error": err, "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
4273 }
4274 return err
4275}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004276
4277// GetDeviceID - TODO: add comment
4278func (dh *deviceHandler) GetDeviceID() string {
4279 return dh.DeviceID
4280}
4281
4282// GetProxyAddressID - TODO: add comment
4283func (dh *deviceHandler) GetProxyAddressID() string {
4284 return dh.device.ProxyAddress.GetDeviceId()
4285}
4286
4287// GetProxyAddressType - TODO: add comment
4288func (dh *deviceHandler) GetProxyAddressType() string {
4289 return dh.device.ProxyAddress.GetDeviceType()
4290}
4291
4292// GetProxyAddress - TODO: add comment
4293func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4294 return dh.device.ProxyAddress
4295}
4296
4297// GetEventProxy - TODO: add comment
4298func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4299 return dh.EventProxy
4300}
4301
4302// GetOmciTimeout - TODO: add comment
4303func (dh *deviceHandler) GetOmciTimeout() int {
4304 return dh.pOpenOnuAc.omciTimeout
4305}
4306
4307// GetAlarmAuditInterval - TODO: add comment
4308func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4309 return dh.pOpenOnuAc.alarmAuditInterval
4310}
4311
4312// GetDlToOnuTimeout4M - TODO: add comment
4313func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4314 return dh.pOpenOnuAc.dlToOnuTimeout4M
4315}
4316
4317// GetUniEntityMap - TODO: add comment
4318func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4319 return &dh.uniEntityMap
4320}
4321
4322// GetPonPortNumber - TODO: add comment
4323func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4324 return &dh.ponPortNumber
4325}
4326
4327// GetUniVlanConfigFsm - TODO: add comment
4328func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004329 dh.lockVlanConfig.RLock()
4330 value := dh.UniVlanConfigFsmMap[uniID]
4331 dh.lockVlanConfig.RUnlock()
4332 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004333}
4334
4335// GetOnuAlarmManager - TODO: add comment
4336func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4337 return dh.pAlarmMgr
4338}
4339
4340// GetOnuMetricsManager - TODO: add comment
4341func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4342 return dh.pOnuMetricsMgr
4343}
4344
4345// GetOnuTP - TODO: add comment
4346func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4347 return dh.pOnuTP
4348}
4349
4350// GetBackendPathPrefix - TODO: add comment
4351func (dh *deviceHandler) GetBackendPathPrefix() string {
4352 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4353}
4354
4355// GetOnuIndication - TODO: add comment
4356func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4357 return dh.pOnuIndication
4358}
4359
4360// RLockMutexDeletionInProgressFlag - TODO: add comment
4361func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4362 dh.mutexDeletionInProgressFlag.RLock()
4363}
4364
4365// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4366func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4367 dh.mutexDeletionInProgressFlag.RUnlock()
4368}
4369
4370// GetDeletionInProgress - TODO: add comment
4371func (dh *deviceHandler) GetDeletionInProgress() bool {
4372 return dh.deletionInProgress
4373}
4374
4375// GetPmConfigs - TODO: add comment
4376func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4377 return dh.pmConfigs
4378}
4379
4380// GetDeviceType - TODO: add comment
4381func (dh *deviceHandler) GetDeviceType() string {
4382 return dh.DeviceType
4383}
4384
4385// GetLogicalDeviceID - TODO: add comment
4386func (dh *deviceHandler) GetLogicalDeviceID() string {
4387 return dh.logicalDeviceID
4388}
4389
4390// GetDevice - TODO: add comment
4391func (dh *deviceHandler) GetDevice() *voltha.Device {
4392 return dh.device
4393}
4394
4395// GetMetricsEnabled - TODO: add comment
4396func (dh *deviceHandler) GetMetricsEnabled() bool {
4397 return dh.pOpenOnuAc.MetricsEnabled
4398}
4399
4400// InitPmConfigs - TODO: add comment
4401func (dh *deviceHandler) InitPmConfigs() {
4402 dh.pmConfigs = &voltha.PmConfigs{}
4403}
4404
4405// GetUniPortMask - TODO: add comment
4406func (dh *deviceHandler) GetUniPortMask() int {
4407 return dh.pOpenOnuAc.config.UniPortMask
4408}