blob: 9fbc5df4f40c931fd1fef4fbf161a6f968503a45 [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
Joey Armstrong89c812c2024-01-12 19:00:20 -05002 * Copyright 2020-2024 Open Networking Foundation (ONF) and the ONF Contributors
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003 *
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
praneeth nalmas5a0a5502022-12-23 15:57:00 +053017// Package core provides the utility for onu devices, flows and statistics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000018package 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"
kesavand011d5162021-11-25 19:21:06 +053047 "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"
52 oop "github.com/opencord/voltha-protos/v5/go/openolt"
mpagenko59862f02021-10-11 08:53:18 +000053 "github.com/opencord/voltha-protos/v5/go/tech_profile"
khenaidoo7d3c5582021-08-11 18:09:44 -040054 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt2b107642022-12-09 07:56:23 +000055 "google.golang.org/grpc/codes"
56 "google.golang.org/grpc/status"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000057)
58
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000059const (
mpagenko101ac942021-11-16 15:01:29 +000060 //constants for reconcile flow check channel
61 cWaitReconcileFlowAbortOnSuccess = 0xFFFD
62 cWaitReconcileFlowAbortOnError = 0xFFFE
63 cWaitReconcileFlowNoActivity = 0xFFFF
64)
65
66const (
67 // constants for timeouts
mpagenko38662d02021-08-11 09:45:19 +000068 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000069)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000070
mpagenko1cc3cb42020-07-27 15:24:38 +000071const (
mpagenko44bd8362021-11-15 11:40:05 +000072 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
73 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
74 // as long as such is not available by the libraries - use this workaround
75 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
76)
77
78const (
mpagenko1cc3cb42020-07-27 15:24:38 +000079 // events of Device FSM
80 devEvDeviceInit = "devEvDeviceInit"
81 devEvGrpcConnected = "devEvGrpcConnected"
82 devEvGrpcDisconnected = "devEvGrpcDisconnected"
83 devEvDeviceUpInd = "devEvDeviceUpInd"
84 devEvDeviceDownInd = "devEvDeviceDownInd"
85)
86const (
87 // states of Device FSM
88 devStNull = "devStNull"
89 devStDown = "devStDown"
90 devStInit = "devStInit"
91 devStConnected = "devStConnected"
92 devStUp = "devStUp"
93)
94
praneeth nalmas5a0a5502022-12-23 15:57:00 +053095// Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
Holger Hildebrandt24d51952020-05-04 14:03:42 +000096const (
Himani Chawla4d908332020-08-31 12:30:20 +053097 pon = voltha.EventSubCategory_PON
98 //olt = voltha.EventSubCategory_OLT
99 //ont = voltha.EventSubCategory_ONT
100 //onu = voltha.EventSubCategory_ONU
101 //nni = voltha.EventSubCategory_NNI
102 //service = voltha.EventCategory_SERVICE
103 //security = voltha.EventCategory_SECURITY
104 equipment = voltha.EventCategory_EQUIPMENT
105 //processing = voltha.EventCategory_PROCESSING
106 //environment = voltha.EventCategory_ENVIRONMENT
107 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000108)
109
110const (
111 cEventObjectType = "ONU"
112)
113const (
114 cOnuActivatedEvent = "ONU_ACTIVATED"
115)
116
mpagenkof1fc3862021-02-16 10:09:52 +0000117type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000118 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000119 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000120}
121
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000122var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
123 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
124 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
125 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
126 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
127 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
128 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
129 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
130 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000131}
132
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000133const (
134 cNoReconciling = iota
135 cOnuConfigReconciling
136 cSkipOnuConfigReconciling
137)
138
Girish Gowdrae95687a2021-09-08 16:30:58 -0700139// FlowCb is the flow control block containing flow add/delete information along with a response channel
140type FlowCb struct {
141 ctx context.Context // Flow handler context
Girish Gowdrae95687a2021-09-08 16:30:58 -0700142 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
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530146 addFlow bool // if true flow to be added, else removed
Girish Gowdrae95687a2021-09-08 16:30:58 -0700147}
148
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530149// deviceHandler will interact with the ONU ? device.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530150type deviceHandler struct {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530151 EventProxy eventif.EventProxy
152
153 device *voltha.Device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000154
khenaidoo7d3c5582021-08-11 18:09:44 -0400155 coreClient *vgrpc.Client
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000156
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800157 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400158 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800159
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000160 pOpenOnuAc *OpenONUAC
161 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530162 //pPonPort *voltha.Port
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530163 deviceEntrySet chan bool //channel for DeviceEntry set event
164 pOnuOmciDevice *mib.OnuDeviceEntry
165 pOnuTP *avcfg.OnuUniTechProf
166 pOnuMetricsMgr *pmmgr.OnuMetricsManager
167 pAlarmMgr *almgr.OnuAlarmManager
168 pSelfTestHdlr *otst.SelfTestControlBlock
169 exitChannel chan int
170 pOnuIndication *oop.OnuIndication
171 pLockStateFsm *uniprt.LockStateFsm
172 pUnlockStateFsm *uniprt.LockStateFsm
173
174 stopCollector chan bool
175 stopAlarmManager chan bool
176 stopHeartbeatCheck chan bool
177 uniEntityMap cmn.OnuUniPortMap
178 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
179 pOnuUpradeFsm *swupg.OnuUpgradeFsm
180 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +0530181 chUniVlanConfigOnRebootDone chan uint16
182 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530183 pLastUpgradeImageState *voltha.ImageState
184 upgradeFsmChan chan struct{}
185
186 deviceDeleteCommChan chan bool
187 DeviceID string
188 DeviceType string
189 adminState string
190 logicalDeviceID string
191 ProxyAddressID string
192 ProxyAddressType string
193 parentID string
194
195 flowCbChan []chan FlowCb
196 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
197 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
198 reconcileExpiryComplete time.Duration
199 reconcileExpiryVlanConfig time.Duration
200 lockDevice sync.RWMutex
201 mutexDeviceReason sync.RWMutex
202 mutexCollectorFlag sync.RWMutex
203 mutextAlarmManagerFlag sync.RWMutex
204 lockVlanConfig sync.RWMutex
205 lockVlanAdd sync.RWMutex
206 lockUpgradeFsm sync.RWMutex
207 mutexReconcilingFlag sync.RWMutex
208 mutexReconcilingFirstPassFlag sync.RWMutex
209 mutexReconcilingReasonUpdate sync.RWMutex
210 mutexReadyForOmciConfig sync.RWMutex
211 mutexDeletionInProgressFlag sync.RWMutex
212 mutexFlowMonitoringRoutineFlag sync.RWMutex
213 mutexForDisableDeviceRequested sync.RWMutex
214 mutexOltAvailable sync.RWMutex
215 mutexKvStoreContext sync.Mutex
216 ponPortNumber uint32
217
218 deviceReason uint8
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000219
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000220 //flowMgr *OpenOltFlowMgr
221 //eventMgr *OpenOltEventMgr
222 //resourceMgr *rsrcMgr.OpenOltResourceMgr
223
224 //discOnus sync.Map
225 //onus sync.Map
226 //portStats *OpenOltStatisticsMgr
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530227 collectorIsRunning bool
228 alarmManagerIsRunning bool
229 upgradeCanceled bool
230 reconciling uint8
231 reconcilingFirstPass bool
232 reconcilingReasonUpdate bool
233 readyForOmciConfig bool
234 deletionInProgress bool
235 disableDeviceRequested bool // this flag identify ONU received disable request or not
236 oltAvailable bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000237}
238
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530239// newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400240func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530241 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400242 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000243 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400244 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000245 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000246 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000247 dh.DeviceType = cloned.Type
248 dh.adminState = "up"
249 dh.device = cloned
250 dh.pOpenOnuAc = adapter
251 dh.exitChannel = make(chan int, 1)
252 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000253 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000254 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000255 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530256 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530257 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000258 dh.stopHeartbeatCheck = make(chan bool, 2)
259 //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 +0000260 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000261 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000262 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000263 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000264 dh.lockUpgradeFsm = sync.RWMutex{}
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300265 dh.mutexForDisableDeviceRequested = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000266 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000267 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000268 dh.reconcilingReasonUpdate = false
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000269 dh.reconcilingFirstPass = true
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300270 dh.disableDeviceRequested = false
Holger Hildebrandt2b107642022-12-09 07:56:23 +0000271 dh.oltAvailable = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000272 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000273 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
274 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
275 if rECSeconds < 2 {
276 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
277 rECSeconds = 2
278 }
279 rEVCSeconds := rECSeconds / 2
280 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000281 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000282 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000283 dh.pLastUpgradeImageState = &voltha.ImageState{
284 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
285 Reason: voltha.ImageState_UNKNOWN_ERROR,
286 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
287 }
288 dh.upgradeFsmChan = make(chan struct{})
praneeth nalmasf405e962023-08-07 15:02:03 +0530289 dh.deviceDeleteCommChan = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000290
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800291 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
292 dh.pmConfigs = cloned.PmConfigs
293 } /* else {
294 // will be populated when onu_metrics_mananger is initialized.
295 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800296
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297 // Device related state machine
298 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000299 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000300 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000301 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
302 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
303 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
304 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
305 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000306 },
307 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000308 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
309 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
310 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
311 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
312 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
313 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
314 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
315 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000316 },
317 )
mpagenkoaf801632020-07-03 10:00:42 +0000318
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000319 return &dh
320}
321
Himani Chawla6d2ae152020-09-02 13:11:20 +0530322// start save the device to the data model
323func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000324 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000325 // Add the initial device to the local model
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000326 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000327}
328
Himani Chawla4d908332020-08-31 12:30:20 +0530329/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000330// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530331func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000332 logger.Debug("stopping-device-handler")
333 dh.exitChannel <- 1
334}
Himani Chawla4d908332020-08-31 12:30:20 +0530335*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000336
337// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530338// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000339
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530340// adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530341func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400342 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000343
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000344 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
praneeth.nalmas2d75f002023-03-31 12:59:59 +0530345
mpagenko1cc3cb42020-07-27 15:24:38 +0000346 if dh.pDeviceStateFsm.Is(devStNull) {
347 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000348 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"device-id": device.Id, "err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000349 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000350 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800351 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
352 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800353 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400354 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000355 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800356 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800357 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000358 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000359 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000360 }
361
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000362}
363
khenaidoo42dcdfd2021-10-19 17:34:12 -0400364func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000365 /* 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 +0530366 //assuming omci message content is hex coded!
367 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000368 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000369 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000370 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000371 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530372 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000373 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000374 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000375 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000376 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
377 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530378 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000379 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
380 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530381}
382
khenaidoo42dcdfd2021-10-19 17:34:12 -0400383func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000384 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000385
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000386 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000387 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000388 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
389 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000390 }
bseeniva0cbc62a2026-01-23 19:08:36 +0530391 dh.lockDevice.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +0530392 if dh.pOnuTP == nil {
393 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000394 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000395 log.Fields{"device-id": dh.DeviceID})
bseeniva0cbc62a2026-01-23 19:08:36 +0530396 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000397 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530398 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000399 if !dh.IsReadyForOmciConfig() {
400 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
401 "device-state": dh.GetDeviceReasonString()})
bseeniva0cbc62a2026-01-23 19:08:36 +0530402 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000403 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530404 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000405 //previous state test here was just this one, now extended for more states to reject the SetRequest:
406 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
407 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530408
Himani Chawla26e555c2020-08-31 12:30:20 +0530409 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000410 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
411 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000412 dh.pOnuTP.LockTpProcMutex()
413 defer dh.pOnuTP.UnlockTpProcMutex()
bseeniva0cbc62a2026-01-23 19:08:36 +0530414 defer dh.lockDevice.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000415
mpagenko44bd8362021-11-15 11:40:05 +0000416 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530417 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
418 techProfMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000419 }
420 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000421 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800422 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000423 logger.Errorw(ctx, "error-parsing-tpid-from-tppath",
424 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800425 return err
426 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000427 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
428 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000429
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000430 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530431
Girish Gowdra50e56422021-06-01 16:46:04 -0700432 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400433 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000434 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
435 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +0000436
437 err = dh.CheckAvailableOnuCapabilities(ctx, pDevEntry, *tpInst.TpInstance)
438 if err != nil {
439 logger.Errorw(ctx, "error-checking-available-onu-capabilities-stopping-device",
440 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
441 // stopping all further processing
442 _ = dh.UpdateInterface(ctx)
443 return err
444 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700445 // if there has been some change for some uni TechProfilePath
446 //in order to allow concurrent calls to other dh instances we do not wait for execution here
447 //but doing so we can not indicate problems to the caller (who does what with that then?)
448 //by now we just assume straightforward successful execution
449 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
450 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530451
Girish Gowdra50e56422021-06-01 16:46:04 -0700452 // deadline context to ensure completion of background routines waited for
453 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
454 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
455 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000456
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000457 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700458
459 var wg sync.WaitGroup
460 wg.Add(1) // for the 1 go routine to finish
461 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000462 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700463 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000464 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
465 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 -0700466 return tpErr
467 }
468 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
469 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530470 defer cancel2()
471 err1 := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx))
472 if err1 != nil {
473 logger.Errorf(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "error": err1})
474 return err
Girish Gowdra50e56422021-06-01 16:46:04 -0700475 }
476 return nil
477 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000478 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700479 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700480 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530481 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000482 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000483 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
484 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530485 return nil
486}
487
khenaidoo42dcdfd2021-10-19 17:34:12 -0400488func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000489 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530490
bseeniva0cbc62a2026-01-23 19:08:36 +0530491 dh.lockDevice.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +0530492 if dh.pOnuTP == nil {
493 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000494 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000495 log.Fields{"device-id": dh.DeviceID})
bseeniva0cbc62a2026-01-23 19:08:36 +0530496 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000497 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530498 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530499 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000500 dh.pOnuTP.LockTpProcMutex()
501 defer dh.pOnuTP.UnlockTpProcMutex()
bseeniva0cbc62a2026-01-23 19:08:36 +0530502 defer dh.lockDevice.RUnlock()
Himani Chawla26e555c2020-08-31 12:30:20 +0530503
mpagenko0f543222021-11-03 16:24:14 +0000504 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
505 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
506 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530507 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
508 delGemPortMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000509 }
510 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000511 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800512 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000513 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
514 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800515 return err
516 }
mpagenko0f543222021-11-03 16:24:14 +0000517 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
518 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000519 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000520
Mahir Gunyel9545be22021-07-04 15:53:16 -0700521 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000522 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000523
Himani Chawla26e555c2020-08-31 12:30:20 +0530524}
525
khenaidoo42dcdfd2021-10-19 17:34:12 -0400526func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000527 logger.Infow(ctx, "delete-tcont-request start", log.Fields{"device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId, "tcont": delTcontMsg.AllocId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000528
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000529 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000530 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000531 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
532 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000533 }
bseeniva0cbc62a2026-01-23 19:08:36 +0530534 dh.lockDevice.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +0530535 if dh.pOnuTP == nil {
536 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000537 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000538 log.Fields{"device-id": dh.DeviceID})
bseeniva0cbc62a2026-01-23 19:08:36 +0530539 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000540 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530541 }
542
Himani Chawla26e555c2020-08-31 12:30:20 +0530543 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000544 dh.pOnuTP.LockTpProcMutex()
545 defer dh.pOnuTP.UnlockTpProcMutex()
bseeniva0cbc62a2026-01-23 19:08:36 +0530546 defer dh.lockDevice.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000547
mpagenko0f543222021-11-03 16:24:14 +0000548 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
549 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
550 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530551 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
552 delTcontMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000553 }
554 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700555 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000556 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800557 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000558 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
559 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800560 return err
561 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000562 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530563
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000564 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
565 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530566 defer cancel()
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000567 logger.Debugw(ctx, "remove-tcont-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "tcont": delTcontMsg.AllocId})
Akash Soni840f8d62024-12-11 19:37:06 +0530568 err1 := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
569 if err1 != nil {
570 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "err": err1})
571 return err1
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000572 }
573
Mahir Gunyel9545be22021-07-04 15:53:16 -0700574 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000575 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000576
Mahir Gunyel9545be22021-07-04 15:53:16 -0700577}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000578
Mahir Gunyel9545be22021-07-04 15:53:16 -0700579func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000580 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
581 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700582 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000583 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
584 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530585 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700586 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000587 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700588 resourceName = "Gem"
589 } else {
590 resourceName = "Tcont"
591 }
592
593 // deadline context to ensure completion of background routines waited for
594 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
595 dctx, cancel := context.WithDeadline(context.Background(), deadline)
596
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000597 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700598
599 var wg sync.WaitGroup
600 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000601 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700602 resource, entryID, &wg)
603 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000604 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
605 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700606 return err
607 }
608
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000609 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
610 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
611 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
612 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700613 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530614 defer cancel2()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700615 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000616 logger.Debugw(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
Akash Soni840f8d62024-12-11 19:37:06 +0530617 err := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx))
618 if err != nil {
619 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "err": err})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700620 return err
621 }
622 }
623 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000624 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700625 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530626 return nil
627}
628
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530629// FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000630func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400631 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400632 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700633 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
634 var errorsList []error
635 var retError error
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +0530636 if dh.GetPersRebootFlag(ctx) {
637 logger.Warnw(ctx, "FlowUpdateIncremental ignored as deivce is being configured post reboot", log.Fields{"device-id": dh.DeviceID})
638 return fmt.Errorf("errors-installing-one-or-more-flows-groups-reboot-in-progress")
639 }
mpagenko01e726e2020-10-23 09:45:29 +0000640 //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 +0000641 if apOfFlowChanges.ToRemove != nil {
642 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000643 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000644 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000645 "device-id": dh.DeviceID})
646 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700647 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000648 continue
649 }
650 flowInPort := flow.GetInPort(flowItem)
651 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000652 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
653 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700654 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000655 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000656 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000657 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000658 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000659 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000660 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000661 continue
662 } else {
663 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000664 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000665 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
666 loUniPort = uniPort
667 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000668 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000669 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000670 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000671 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700672 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000673 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000674 }
675 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000676 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000677 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
678 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700679
680 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
681 // Step1 : Fill flowControlBlock
682 // Step2 : Push the flowControlBlock to ONU channel
683 // Step3 : Wait on response channel for response
684 // Step4 : Return error value
685 startTime := time.Now()
686 respChan := make(chan error)
687 flowCb := FlowCb{
688 ctx: ctx,
689 addFlow: false,
690 flowItem: flowItem,
691 flowMetaData: nil,
692 uniPort: loUniPort,
693 respChan: &respChan,
694 }
695 dh.flowCbChan[loUniPort.UniID] <- flowCb
696 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
697 // Wait on the channel for flow handlers return value
698 retError = <-respChan
699 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
700 if retError != nil {
701 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
702 log.Fields{"device-id": dh.DeviceID, "error": retError})
703 errorsList = append(errorsList, retError)
704 continue
705 }
706 } else {
707 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
708 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000709 }
710 }
711 }
712 }
mpagenko01e726e2020-10-23 09:45:29 +0000713 if apOfFlowChanges.ToAdd != nil {
714 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
715 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000716 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000717 "device-id": dh.DeviceID})
718 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700719 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000720 continue
721 }
722 flowInPort := flow.GetInPort(flowItem)
723 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000724 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
725 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700726 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000727 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000728 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000729 } else if flowInPort == dh.ponPortNumber {
730 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000731 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000732 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000733 continue
734 } else {
735 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000736 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000737 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
738 loUniPort = uniPort
739 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000740 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000741 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000742 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000743 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700744 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000745 continue
mpagenko01e726e2020-10-23 09:45:29 +0000746 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000747 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
748 // if not, we just throw some error here to have an indication about that, if we really need to support that
749 // then we would need to create some means to activate the internal stored flows
750 // after the device gets active automatically (and still with its dependency to the TechProfile)
751 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
752 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000753 if !dh.IsReadyForOmciConfig() {
754 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
755 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700756 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
757 errorsList = append(errorsList, retError)
758 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000759 }
760
mpagenko01e726e2020-10-23 09:45:29 +0000761 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000762 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000763 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
764 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700765 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
766 // Step1 : Fill flowControlBlock
767 // Step2 : Push the flowControlBlock to ONU channel
768 // Step3 : Wait on response channel for response
769 // Step4 : Return error value
770 startTime := time.Now()
771 respChan := make(chan error)
772 flowCb := FlowCb{
773 ctx: ctx,
774 addFlow: true,
775 flowItem: flowItem,
776 flowMetaData: apFlowMetaData,
777 uniPort: loUniPort,
778 respChan: &respChan,
779 }
780 dh.flowCbChan[loUniPort.UniID] <- flowCb
781 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
782 // Wait on the channel for flow handlers return value
783 retError = <-respChan
784 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
785 if retError != nil {
786 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
787 log.Fields{"device-id": dh.DeviceID, "error": retError})
788 errorsList = append(errorsList, retError)
789 continue
790 }
791 } else {
792 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
793 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000794 }
795 }
796 }
797 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700798 if len(errorsList) > 0 {
799 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
800 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
801 }
802 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000803}
804
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530805// disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
806// following are the expected device states after this activity:
807// Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
mpagenkofc4f56e2020-11-04 17:17:49 +0000808// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000809func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
810 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300811 dh.mutexForDisableDeviceRequested.Lock()
812 dh.disableDeviceRequested = true
813 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000814 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000815 //note that disableDevice sequences in some 'ONU active' state may yield also
816 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000817 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000818 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000819 //disable-device shall be just a UNi/ONU-G related admin state setting
820 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000821
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000822 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000823 // disable UNI ports/ONU
824 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
825 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000826 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000827 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000828 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000829 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000830 }
831 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000832 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000833 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000834 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400835 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000836 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000837 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400838 OperStatus: voltha.OperStatus_UNKNOWN,
839 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000840 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000841 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000842 }
mpagenko01e726e2020-10-23 09:45:29 +0000843 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000844
845 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000846 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000847 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300848 }
849}
850
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530851// reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000852func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
853 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000854
mpagenkoaa3afe92021-05-21 16:20:58 +0000855 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000856 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
857 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
858 // for real ONU's that should have nearly no influence
859 // Note that for real ONU's there is anyway a problematic situation with following sequence:
860 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
861 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
862 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000863 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000864
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000865 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000866 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300867 dh.mutexForDisableDeviceRequested.Lock()
868 dh.disableDeviceRequested = false
869 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000870 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000871 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000872 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000873 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000874 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000875 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300876}
877
dbainbri4d3a0dc2020-12-02 00:33:42 +0000878func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530879 logger.Info(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000880
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000881 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000882 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000883 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000884 return
885 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000886 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000887 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000888 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000889 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000890 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000891 }
mpagenko101ac942021-11-16 15:01:29 +0000892 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000893 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000894 }
Himani Chawla4d908332020-08-31 12:30:20 +0530895 var onuIndication oop.OnuIndication
akashreddykb03dde02025-12-02 10:53:18 +0530896 var rebootInProgress bool
897 var persUniUnlockDone bool
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000898 pDevEntry.MutexPersOnuConfig.RLock()
899 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
900 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
901 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
902 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
akashreddykb03dde02025-12-02 10:53:18 +0530903 rebootInProgress = pDevEntry.SOnuPersistentData.PersRebootInProgress
904 persUniUnlockDone = pDevEntry.SOnuPersistentData.PersUniUnlockDone
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000905 pDevEntry.MutexPersOnuConfig.RUnlock()
akashreddykb03dde02025-12-02 10:53:18 +0530906 if rebootInProgress {
907 if persUniUnlockDone {
908 logger.Warnw(ctx, "ONU indication shows reboot in progress - cannot proceed with reconciliation", log.Fields{"device-id": dh.DeviceID})
909 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
910 return
911 }
912 }
913 if onuIndication.OperState == "up" {
914 if err := dh.createInterface(ctx, &onuIndication); err != nil {
915 logger.Errorw(ctx, "failed to handle device up indication", log.Fields{"device-id": dh.DeviceID, "error": err})
916 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
917 return
918 }
919 } else {
920 logger.Warnw(ctx, "ONU indication does not have 'up' state, cannot proceed with reconciliation", log.Fields{"device-id": dh.DeviceID, "operState": onuIndication.OperState})
921 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
922 return
923 }
924 logger.Debugw(ctx, "reconciling - simulate onu indication done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000925}
926
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000927func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530928 logger.Info(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000929
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000930 continueWithFlowConfig := false
931
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000932 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000933 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000934 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000935 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
936 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000937 }
bseeniva0cbc62a2026-01-23 19:08:36 +0530938 dh.lockDevice.RLock()
939 if dh.pOnuTP == nil {
940 //should normally not happen ...
941 logger.Warnw(ctx, "onuTechProf instance not set up for reconcile tech prof - ignoring request",
942 log.Fields{"device-id": dh.DeviceID})
943 dh.lockDevice.RUnlock()
944 return continueWithFlowConfig
945 }
946
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000947 dh.pOnuTP.LockTpProcMutex()
948 defer dh.pOnuTP.UnlockTpProcMutex()
bseeniva0cbc62a2026-01-23 19:08:36 +0530949 defer dh.lockDevice.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000950
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000951 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000952 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000953 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
954 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530955 logger.Info(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000956 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000957 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
958 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000959 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000960 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700961 techProfsFound := false
962 techProfInstLoadFailed := false
963outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000964 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000965 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000966 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000967 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000968 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000969 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000970 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000971 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000972 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
973 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000974 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000975 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000976 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700977 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000978 var iaTechTpInst ia.TechProfileDownloadMessage
979 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800980 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000981 pDevEntry.MutexReconciledTpInstances.RLock()
982 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
983 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000984 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000985 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700986 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000987 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700988 break outerLoop
989 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000990 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000991 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700992 var tpInst tech_profile.TechProfileInstance
993 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400994 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700995 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000996 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000997 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700998 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000999 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001000 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001001 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
1002 break outerLoop
1003 }
1004
Girish Gowdra041dcb32020-11-16 16:54:30 -08001005 // deadline context to ensure completion of background routines waited for
1006 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
1007 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001008 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001009
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001010 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -08001011 var wg sync.WaitGroup
1012 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001013 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001014 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001015 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
1016 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001017 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
1018 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -08001019 }
mpagenko2dc896e2021-08-02 12:03:59 +00001020 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001021 if len(uniData.PersFlowParams) != 0 {
1022 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001023 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001024 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +00001025 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001026 } // for all UNI entries from SOnuPersistentData
1027 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
1028 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001029 }
mpagenko2dc896e2021-08-02 12:03:59 +00001030
1031 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
1032 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001033
1034 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +00001035}
1036
1037func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
1038 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
1039 if !abTechProfsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301040 logger.Warn(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001041 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001042 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001043 return
1044 }
mpagenko2dc896e2021-08-02 12:03:59 +00001045 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001046 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +00001047 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -07001048 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001049 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001050 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001051 }
mpagenko2dc896e2021-08-02 12:03:59 +00001052 if !abFlowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301053 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001054 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001055 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001056 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001057}
1058
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001059func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
1060 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001061
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001062 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001063 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001064 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001065 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001066 return
1067 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001068
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001069 pDevEntry.MutexPersOnuConfig.RLock()
1070 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1071 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301072 logger.Warn(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001073 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001074 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001075 return
1076 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001077 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001078 var uniVlanConfigEntries []uint8
1079 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1080
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001081 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001082 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1083 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001084 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001085 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001086 continue
1087 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001088 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001089 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001090 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001091 // It doesn't make sense to configure any flows if no TPs are available
1092 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001093 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001094 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1095 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001096 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001097 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001098
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001099 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001100 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001101 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001102 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001103 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1104 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001105 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001106 return
1107 }
mpagenko101ac942021-11-16 15:01:29 +00001108 //needed to split up function due to sca complexity
1109 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1110
mpagenko2dc896e2021-08-02 12:03:59 +00001111 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001112 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001113 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1114 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001115 // this can't be used as global finished reconciling flag because
1116 // assumes is getting called before the state machines for the last flow is completed,
1117 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001118 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1119 } // for all UNI entries from SOnuPersistentData
1120 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001121
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001122 if !flowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301123 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001124 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001125 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001126 return
1127 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001128 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1129 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1130 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1131 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1132 log.Fields{"device-id": dh.DeviceID})
1133 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1134 if pDevEntry != nil {
1135 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001136 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001137 } else {
1138 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1139 log.Fields{"device-id": dh.DeviceID})
1140 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1141 if pDevEntry != nil {
1142 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1143 }
1144 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001145 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001146 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001147}
1148
mpagenko101ac942021-11-16 15:01:29 +00001149func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1150 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1151 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1152 flowsProcessed := 0
1153 lastFlowToReconcile := false
1154 loUniID := apUniPort.UniID
1155 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001156 if !(*apFlowsFound) {
1157 *apFlowsFound = true
1158 syncChannel := make(chan struct{})
1159 // start go routine with select() on reconciling vlan config channel before
1160 // starting vlan config reconciling process to prevent loss of any signal
1161 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1162 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1163 //block until the wait routine is really blocked on channel input
1164 // in order to prevent to early ready signal from VlanConfig processing
1165 <-syncChannel
1166 }
1167 if flowsProcessed == len(aPersFlowParam)-1 {
1168 var uniAdded bool
1169 lastFlowToReconcile = true
1170 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1171 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001172 }
1173 }
mpagenko101ac942021-11-16 15:01:29 +00001174 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1175 "device-id": dh.DeviceID, "uni-id": loUniID,
1176 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1177 dh.lockVlanConfig.Lock()
1178 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1179 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1180 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301181 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid), uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, lastFlowToReconcile, false, flowData.Meter, nil); err != nil {
mpagenko101ac942021-11-16 15:01:29 +00001182 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1183 }
1184 } else {
1185 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05301186 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301187 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, lastFlowToReconcile, false, flowData.Meter, nil); err != nil {
mpagenko101ac942021-11-16 15:01:29 +00001188 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1189 }
1190 }
1191 dh.lockVlanConfig.Unlock()
1192 flowsProcessed++
1193 } //for all flows of this UNI
1194}
1195
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301196// waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1197//
1198// and decrements the according handler wait group waiting for these indications
mpagenko101ac942021-11-16 15:01:29 +00001199func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1200 waitGroup *cmn.WaitGroupWithTimeOut) {
1201 var reconciledUniVlanConfigEntries []uint8
1202 var appended bool
1203 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1204 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1205 "device-id": dh.DeviceID, "expiry": expiry})
1206 // indicate blocking on channel now to the caller
1207 aSyncChannel <- struct{}{}
1208 for {
1209 select {
1210 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1211 switch uniIndication {
1212 // no activity requested (should normally not be received) - just continue waiting
1213 case cWaitReconcileFlowNoActivity:
1214 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1215 case cWaitReconcileFlowAbortOnError:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301216 logger.Warn(ctx, "waitReconcileFlow aborted on error",
mpagenko101ac942021-11-16 15:01:29 +00001217 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1218 return
1219 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1220 case cWaitReconcileFlowAbortOnSuccess:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301221 logger.Warn(ctx, "waitReconcileFlow aborted on success",
mpagenko101ac942021-11-16 15:01:29 +00001222 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1223 return
1224 // this should be a valid UNI vlan config done indication
1225 default:
1226 if uniIndication < platform.MaxUnisPerOnu {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301227 logger.Info(ctx, "reconciling flows has been finished in time for this UNI",
mpagenko101ac942021-11-16 15:01:29 +00001228 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1229 if reconciledUniVlanConfigEntries, appended =
1230 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1231 waitGroup.Done()
1232 }
1233 } else {
Akash Soni840f8d62024-12-11 19:37:06 +05301234 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored", log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
mpagenko101ac942021-11-16 15:01:29 +00001235 }
1236 } //switch uniIndication
1237
1238 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1239 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1240 log.Fields{"device-id": dh.DeviceID})
1241 return
1242 }
1243 }
1244}
1245
1246func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1247 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1248}
1249
1250func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1251 for _, ele := range slice {
1252 if ele == val {
1253 return slice, false
1254 }
1255 }
1256 return append(slice, val), true
1257}
1258
1259// sendChReconcileFinished - sends true or false on reconcileFinish channel
1260func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1261 if dh != nil { //if the object still exists (might have been already deleted in background)
1262 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1263 select {
1264 case dh.chReconcilingFinished <- success:
1265 default:
1266 }
1267 }
1268}
1269
1270// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1271func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1272 if dh != nil { //if the object still exists (might have been already deleted in background)
1273 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1274 select {
1275 case dh.chUniVlanConfigReconcilingDone <- value:
1276 default:
1277 }
1278 }
1279}
1280
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301281func (dh *deviceHandler) DeviceFlowConfigOnReboot(ctx context.Context) {
1282 logger.Debugw(ctx, "rebooting - trigger flow config", log.Fields{"device-id": dh.DeviceID})
1283
1284 defer dh.UpdateAndStoreRebootState(ctx, false)
1285 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
1286 if pDevEntry == nil {
1287 logger.Errorw(ctx, "rebooting - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1288 return
1289 }
1290
1291 pDevEntry.MutexPersOnuConfig.RLock()
1292 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1293 pDevEntry.MutexPersOnuConfig.RUnlock()
1294 logger.Warn(ctx, "rebooting - no uni-configs have been stored - aborting",
1295 log.Fields{"device-id": dh.DeviceID})
1296 return
1297 }
1298 flowsFound := false
1299 var uniVlanConfigEntries []uint8
1300 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1301
1302 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
1303 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1304 if len(uniData.PersFlowParams) == 0 {
1305 logger.Debugw(ctx, "rebooting - no flows stored for uniID",
1306 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1307 continue
1308 }
1309 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
1310 logger.Warnw(ctx, "rebooting - but no TPs stored for uniID, abort",
1311 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1312 // It doesn't make sense to configure any flows if no TPs are available
1313 continue
1314 }
1315 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1316 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
1317 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1318 pDevEntry.MutexPersOnuConfig.RUnlock()
1319
1320 var uniPort *cmn.OnuUniPort
1321 var exist bool
1322 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
1323 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
1324 logger.Errorw(ctx, "rebooting - OnuUniPort data not found - terminate flow config",
1325 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
1326 return
1327 }
1328
1329 dh.updateOnRebootFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1330
1331 logger.Debugw(ctx, "rebooting - flows processed", log.Fields{
1332 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
1333 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1334 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
1335 // this can't be used as global finished reconciling flag because
1336 // assumes is getting called before the state machines for the last flow is completed,
1337 // while this is not guaranteed.
1338 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1339 } // for all UNI entries from SOnuPersistentData
1340 pDevEntry.MutexPersOnuConfig.RUnlock()
1341
1342 if !flowsFound {
1343 logger.Warn(ctx, "rebooting - no flows have been stored before device reboot - terminate flow config",
1344 log.Fields{"device-id": dh.DeviceID})
1345 return
1346 }
1347 logger.Debugw(ctx, "rebooting - waiting on ready indication of requested UNIs", log.Fields{
1348 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1349 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1350 logger.Debugw(ctx, "rebooting - flow config for all UNI's has been finished in time",
1351 log.Fields{"device-id": dh.DeviceID})
1352 } else {
1353 logger.Errorw(ctx, "rebooting - timeout waiting for flow config for all UNI's to be finished!",
1354 log.Fields{"device-id": dh.DeviceID})
1355 return
1356 }
1357}
1358
1359func (dh *deviceHandler) UpdateAndStoreRebootState(ctx context.Context, flag bool) {
1360 dh.UpdateRebootPersData(ctx, flag)
1361 if err := dh.StorePersistentData(ctx); err != nil {
1362 logger.Errorw(ctx, "rebooting - failed to store persistent data in kv store", log.Fields{"device-id": dh.DeviceID})
1363 }
1364}
1365
1366func (dh *deviceHandler) updateOnRebootFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1367 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1368 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1369 flowsProcessed := 0
1370 lastFlowToConfigOnReboot := false
1371 loUniID := apUniPort.UniID
1372 for _, flowData := range aPersFlowParam {
1373 if !(*apFlowsFound) {
1374 *apFlowsFound = true
1375 syncChannel := make(chan struct{})
1376 // start go routine with select() on reconciling vlan config channel before
1377 // starting vlan config reconciling process to prevent loss of any signal
1378 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1379 go dh.waitOnUniVlanConfigOnRebootReady(ctx, syncChannel, apWaitGroup)
1380 //block until the wait routine is really blocked on channel input
1381 // in order to prevent to early ready signal from VlanConfig processing
1382 <-syncChannel
1383 }
1384 if flowsProcessed == len(aPersFlowParam)-1 {
1385 var uniAdded bool
1386 lastFlowToConfigOnReboot = true
1387 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1388 apWaitGroup.Add(1) //increment the waiting group
1389 }
1390 }
1391 logger.Debugw(ctx, "rebooting - add flow with cookie slice", log.Fields{
1392 "device-id": dh.DeviceID, "uni-id": loUniID,
1393 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1394 dh.lockVlanConfig.Lock()
1395 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1396 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1397 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
1398 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid), uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, false, lastFlowToConfigOnReboot, flowData.Meter, nil); err != nil {
1399 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1400 }
1401 } else {
1402 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
1403 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
1404 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, false, lastFlowToConfigOnReboot, flowData.Meter, nil); err != nil {
1405 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1406 }
1407 }
1408 dh.lockVlanConfig.Unlock()
1409 flowsProcessed++
1410 } //for all flows of this UNI
1411}
1412
1413func (dh *deviceHandler) waitOnUniVlanConfigOnRebootReady(ctx context.Context, aSyncChannel chan<- struct{},
1414 waitGroup *cmn.WaitGroupWithTimeOut) {
1415 var rebootUniVlanConfigEntries []uint8
1416 var appended bool
1417 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1418 logger.Debugw(ctx, "start waiting on vlanConfig ready indications on reboot", log.Fields{
1419 "device-id": dh.DeviceID, "expiry": expiry})
1420 // indicate blocking on channel now to the caller
1421 aSyncChannel <- struct{}{}
1422 for {
1423 select {
1424 case <-dh.deviceDeleteCommChan:
1425 // Cancel the context and return
1426 logger.Warnw(ctx, "Device Deletion invoked , stop further processing ", log.Fields{"device-id": dh.DeviceID})
1427 return
1428
1429 case uniIndication := <-dh.chUniVlanConfigOnRebootDone:
1430 switch uniIndication {
1431 // this should be a valid UNI vlan config done indication
1432 default:
1433 if uniIndication < platform.MaxUnisPerOnu {
1434 logger.Info(ctx, "rebooting - configuring flows has been finished in time for this UNI",
1435 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1436 if rebootUniVlanConfigEntries, appended =
1437 dh.appendIfMissing(rebootUniVlanConfigEntries, uint8(uniIndication)); appended {
1438 waitGroup.Done()
1439 }
1440 } else {
1441 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored", log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1442 }
1443 } //switch uniIndication
1444
1445 case <-time.After(expiry):
1446 logger.Errorw(ctx, "timeout waiting for configuring all UNI flows to be finished!",
1447 log.Fields{"device-id": dh.DeviceID})
1448 return
1449 }
1450 }
1451}
1452
1453func (dh *deviceHandler) SendChUniVlanConfigFinishedOnReboot(value uint16) {
1454 if dh != nil { //if the object still exists (might have been already deleted in background)
1455 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1456 select {
1457 case dh.chUniVlanConfigOnRebootDone <- value:
1458 default:
1459 }
1460 }
1461}
1462
1463func (dh *deviceHandler) CheckForDeviceTechProf(ctx context.Context) bool {
1464 logger.Info(ctx, "Check for tech profile config", log.Fields{"device-id": dh.DeviceID})
1465 techProfInstLoadFailed := false
1466 continueWithFlowConfig := false
1467 defer dh.UpdateAndStoreRebootState(ctx, continueWithFlowConfig)
1468 // Stop any on going reconciling thread as the flow configuration post reboot will be performed here
1469 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
1470
1471 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
1472 if pDevEntry == nil {
1473 logger.Errorw(ctx, "no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1474 return continueWithFlowConfig
1475 }
1476 dh.lockDevice.RLock()
1477 if dh.pOnuTP == nil {
1478 //should normally not happen ...
1479 logger.Warnw(ctx, "onuTechProf instance not set up - ignoring request",
1480 log.Fields{"device-id": dh.DeviceID})
1481 dh.lockDevice.RUnlock()
1482 return continueWithFlowConfig
1483 }
1484
1485 dh.pOnuTP.LockTpProcMutex()
1486 defer dh.pOnuTP.UnlockTpProcMutex()
1487 defer dh.lockDevice.RUnlock()
1488
1489 pDevEntry.MutexPersOnuConfig.RLock()
1490 persMutexLock := true
1491 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1492 pDevEntry.MutexPersOnuConfig.RUnlock()
1493 logger.Info(ctx, "no uni-configs have been stored - aborting",
1494 log.Fields{"device-id": dh.DeviceID})
1495 return continueWithFlowConfig
1496 }
1497
1498outerLoop:
1499 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
1500 uniID := uniData.PersUniID
1501
1502 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
1503 logger.Debugw(ctx, "no TPs stored for uniID",
1504 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
1505 continue
1506 }
1507 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
1508 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
1509 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1510 pDevEntry.MutexPersOnuConfig.RUnlock()
1511 persMutexLock = false
1512 for tpID, tpPath := range uniData.PersTpPathMap {
1513 if tpPath != "" {
1514 logger.Infow(ctx, "Starting retrieval for TechProfileInstance", log.Fields{
1515 "uniID": uniID, "tpID": tpID, "tpPath": tpPath, "device-id": dh.DeviceID,
1516 })
1517 // Attempt the initial call before entering the retry loop
1518 iaTechTpInst, err := dh.GetTechProfileInstanceFromParentAdapter(ctx, uniID, tpPath)
1519 if err != nil {
1520 logger.Warnw(ctx, "Starting retrieval for TechProfileInstance", log.Fields{
1521 "uniID": uniID, "tpID": tpID, "tpPath": tpPath, "device-id": dh.DeviceID,
1522 })
1523 techProfInstLoadFailed = true
1524 break outerLoop
1525 }
1526 if iaTechTpInst != nil {
1527 var tpInst tech_profile.TechProfileInstance
1528 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
1529 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
1530 tpInst = *techTpInst.TpInstance
1531 logger.Debugw(ctx, "received-tp-instance-successfully-after-reboot", log.Fields{
1532 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1533 default: // do not support epon or other tech
1534 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
1535 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1536 techProfInstLoadFailed = true
1537 break outerLoop
1538 }
1539
1540 continueWithFlowConfig = true
1541 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
1542 dctx, cancel := context.WithDeadline(ctx, deadline)
1543
1544 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
1545 var wg sync.WaitGroup
1546 wg.Add(1) // for the 1 go routine to finish
1547 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
1548 // Wait for either completion or cancellation
1549 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwldDuringReboot")
1550 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
1551 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.DeviceID, "err": tpErr, "tp-path": uniData.PersTpPathMap[tpID]})
1552 techProfInstLoadFailed = true
1553 continueWithFlowConfig = false
1554 break outerLoop
1555 }
1556 } else {
1557 logger.Errorw(ctx, "Tp instance is not valid", log.Fields{"tp-id": tpID, "tpPath": tpPath, "device-id": dh.DeviceID, "err": err})
1558 techProfInstLoadFailed = true
1559 break outerLoop
1560 }
1561 } else {
1562 logger.Errorw(ctx, "Tp instance is nil", log.Fields{"tp-id": tpID, "tpPath": tpPath,
1563 "uni-id": uniID, "device-id": dh.DeviceID})
1564 techProfInstLoadFailed = true
1565 break outerLoop
1566 }
1567 }
1568 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1569 persMutexLock = true
1570 }
1571 if persMutexLock {
1572 pDevEntry.MutexPersOnuConfig.RUnlock()
1573 }
1574 go dh.deviceRebootStateUpdate(ctx, techProfInstLoadFailed)
1575 return continueWithFlowConfig
1576}
1577
dbainbri4d3a0dc2020-12-02 00:33:42 +00001578func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001579 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001580
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001581 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001582 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001583 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001584 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001585 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001586 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001587
1588 // deadline context to ensure completion of background routines waited for
1589 //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 +05301590 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001591 dctx, cancel := context.WithDeadline(ctx, deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05301592 defer cancel()
1593 err := pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx))
1594 if err != nil {
1595 logger.Errorw(ctx, "delete data from onu kv store failed", log.Fields{"device-id": dh.DeviceID, "err": err})
1596 return err
1597 }
1598 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001599}
1600
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301601// func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
mpagenko15ff4a52021-03-02 10:09:20 +00001602// before this change here return like this was used:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301603//
1604// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
1605//
1606// was and is called in background - error return does not make sense
akashreddyke30dfa92025-11-26 10:51:57 +05301607func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001608 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001609 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001610 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
akashreddyke30dfa92025-11-26 10:51:57 +05301611 return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +03001612 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001613 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301614 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001615 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
akashreddyke30dfa92025-11-26 10:51:57 +05301616 return err
Himani Chawla4d908332020-08-31 12:30:20 +05301617 }
mpagenko01e726e2020-10-23 09:45:29 +00001618
1619 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001620 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001621
mpagenko44bd8362021-11-15 11:40:05 +00001622 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001623 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001624 // do not set the ConnStatus here as it may conflict with the parallel setting from ONU down indication (updateInterface())
akashreddyke30dfa92025-11-26 10:51:57 +05301625 go func() {
1626 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
1627 DeviceId: dh.DeviceID,
1628 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
1629 OperStatus: voltha.OperStatus_DISCOVERED,
1630 }); err != nil {
1631 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1632 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
1633 return
1634 }
akashreddykb03dde02025-12-02 10:53:18 +05301635 dh.UpdateAndStoreRebootState(ctx, true)
akashreddyke30dfa92025-11-26 10:51:57 +05301636 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
1637 logger.Errorw(ctx, "errror-updating-device-reason-to-core", log.Fields{"device-id": dh.DeviceID, "error": err})
1638 return
1639 }
1640 dh.SetReadyForOmciConfig(false)
1641 }()
1642 return nil
mpagenko8b07c1b2020-11-26 10:36:31 +00001643 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1644 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1645 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1646 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001647}
1648
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301649// doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
1650//
1651// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001652func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001653 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001654 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001655 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001656
1657 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001658 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001659 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001660 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1661 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001662 }
1663
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001664 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001665 var inactiveImageID uint16
1666 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1667 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001668 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1669 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001670 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001671 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001672 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001673 if err == nil {
1674 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1675 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001676 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001677 }
1678 } else {
1679 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001680 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001681 }
mpagenko15ff4a52021-03-02 10:09:20 +00001682 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001683 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001684 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001685 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1686 dh.upgradeCanceled = true
1687 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1688 }
mpagenko38662d02021-08-11 09:45:19 +00001689 //no effort spent anymore for the old API to automatically cancel and restart the download
1690 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001691 }
mpagenko15ff4a52021-03-02 10:09:20 +00001692 } else {
1693 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001694 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001695 }
1696 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001697 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1698 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001699 }
1700 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001701}
1702
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301703// onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
mpagenkoc26d4c02021-05-06 14:27:57 +00001704// after the OnuImage has been downloaded to the adapter, called in background
1705func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001706 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001707
1708 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001709 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001710 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001711 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001712 return
1713 }
1714
1715 var inactiveImageID uint16
1716 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1717 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001718 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001719
mpagenko59862f02021-10-11 08:53:18 +00001720 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001721 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001722 // but must be still locked at calling createOnuUpgradeFsm
1723 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1724 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1725 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001726 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1727 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001728 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001729 //flush the remove upgradeFsmChan channel
1730 select {
1731 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001732 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001733 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001734 }
mpagenko59862f02021-10-11 08:53:18 +00001735 dh.lockUpgradeFsm.Unlock()
1736 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1737 dh.upgradeCanceled = true
1738 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1739 }
mpagenko38662d02021-08-11 09:45:19 +00001740 select {
1741 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001742 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001743 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1744 return
1745 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001746 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001747 }
mpagenko59862f02021-10-11 08:53:18 +00001748 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001749 }
mpagenko38662d02021-08-11 09:45:19 +00001750
1751 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001752 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001753 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001754 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001755 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001756 if err == nil {
1757 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1758 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1759 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001760 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001761 return
1762 }
mpagenko38662d02021-08-11 09:45:19 +00001763 } else {
1764 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001765 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001766 }
1767 return
1768 }
1769 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001770 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001771}
1772
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301773// onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001774func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1775 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001776 var err error
1777 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1778 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1779 // 2.) activation of the inactive image
1780
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001781 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001782 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001783 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1784 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001785 }
1786 dh.lockUpgradeFsm.RLock()
1787 if dh.pOnuUpradeFsm != nil {
1788 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001789 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001790 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001791 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1792 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001793 }
mpagenko59862f02021-10-11 08:53:18 +00001794 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1795 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1796 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1797 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001798 // use the OnuVendor identification from this device for the internal unique name
1799 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001800 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001801 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001802 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001803 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001804 "device-id": dh.DeviceID, "error": err})
1805 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001806 }
mpagenko183647c2021-06-08 15:25:04 +00001807 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001808 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001809 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001810 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001811 } //else
1812 dh.lockUpgradeFsm.RUnlock()
1813
1814 // 2.) check if requested image-version equals the inactive one and start its activation
1815 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1816 var inactiveImageID uint16
1817 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1818 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001819 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1820 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001821 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001822 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001823 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001824 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001825 if err == nil {
1826 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1827 inactiveImageID, aCommitRequest); err != nil {
1828 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001829 "device-id": dh.DeviceID, "error": err})
1830 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001831 }
1832 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001833 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001834 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001835 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001836 } //else
1837 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001838 "device-id": dh.DeviceID, "error": err})
1839 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001840}
1841
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301842// onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001843func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1844 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001845 var err error
1846 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1847 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1848 // 2.) commitment of the active image
1849
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001850 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001851 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001852 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1853 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001854 }
1855 dh.lockUpgradeFsm.RLock()
1856 if dh.pOnuUpradeFsm != nil {
1857 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001858 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001859 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001860 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1861 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001862 }
mpagenko59862f02021-10-11 08:53:18 +00001863 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1864 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1865 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1866 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001867 // use the OnuVendor identification from this device for the internal unique name
1868 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001869 // 1.) check a started upgrade process and relay the commitment request to it
1870 // the running upgrade may be based either on the imageIdentifier (started from download)
1871 // or on the imageVersion (started from pure activation)
1872 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1873 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001874 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001875 "device-id": dh.DeviceID, "error": err})
1876 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001877 }
mpagenko183647c2021-06-08 15:25:04 +00001878 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001879 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001880 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001881 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001882 } //else
1883 dh.lockUpgradeFsm.RUnlock()
1884
mpagenko183647c2021-06-08 15:25:04 +00001885 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001886 var activeImageID uint16
1887 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1888 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001889 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1890 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001891 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001892 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001893 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001894 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001895 if err == nil {
1896 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1897 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001898 "device-id": dh.DeviceID, "error": err})
1899 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001900 }
1901 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001902 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001903 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001904 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001905 } //else
1906 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001907 "device-id": dh.DeviceID, "error": err})
1908 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001909}
1910
mpagenkoaa3afe92021-05-21 16:20:58 +00001911func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001912 aVersion string) *voltha.ImageState {
1913 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001914 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001915 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001916 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001917 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1918 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1919 if aVersion == dh.pLastUpgradeImageState.Version {
1920 pImageState = dh.pLastUpgradeImageState
1921 } else { //state request for an image version different from last processed image version
1922 pImageState = &voltha.ImageState{
1923 Version: aVersion,
1924 //we cannot state something concerning this version
1925 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1926 Reason: voltha.ImageState_NO_ERROR,
1927 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1928 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001929 }
1930 }
mpagenko38662d02021-08-11 09:45:19 +00001931 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001932}
1933
1934func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1935 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001936 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001937 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001938 dh.lockUpgradeFsm.RLock()
1939 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001940 dh.lockUpgradeFsm.RUnlock()
1941 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001942 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001943 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1944 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1945 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1946 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1947 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1948 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001949 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1950 dh.upgradeCanceled = true
1951 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1952 }
mpagenko45586762021-10-01 08:30:22 +00001953 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001954 } else {
mpagenko45586762021-10-01 08:30:22 +00001955 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001956 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1957 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1958 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1959 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1960 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1961 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001962 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1963 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001964 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1965 //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 +00001966 }
1967}
1968
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001969func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1970
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001971 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001972
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001973 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001974 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001975 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1976 pDevEntry.MutexOnuImageStatus.Lock()
1977 pDevEntry.POnuImageStatus = onuImageStatus
1978 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001979
1980 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001981 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001982 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1983 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001984 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1985 pDevEntry.MutexOnuImageStatus.Lock()
1986 pDevEntry.POnuImageStatus = nil
1987 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001988 return images, err
1989}
1990
Himani Chawla6d2ae152020-09-02 13:11:20 +05301991// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001992// #####################################################################################
1993
1994// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301995// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001996
dbainbri4d3a0dc2020-12-02 00:33:42 +00001997func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001998 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1999 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002000}
2001
2002// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00002003func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002004
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002005 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002006 var err error
2007
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002008 // populate what we know. rest comes later after mib sync
2009 dh.device.Root = false
2010 dh.device.Vendor = "OpenONU"
2011 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002012 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00002013 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002014
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002015 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002016
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002017 if !dh.IsReconciling() {
2018 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302019 if err = dh.updateDeviceInCore(ctx, dh.device); err != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -04002020 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2021 }
Himani Chawlac07fda02020-12-09 16:21:21 +05302022 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002023 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302024 logger.Infow(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002025 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002026 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002027
Himani Chawla4d908332020-08-31 12:30:20 +05302028 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002029 dh.ponPortNumber = dh.device.ParentPortNo
2030
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002031 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
2032 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
2033 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002034 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002035 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05302036 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002037
2038 /*
2039 self._pon = PonPort.create(self, self._pon_port_number)
2040 self._pon.add_peer(self.parent_id, self._pon_port_number)
2041 self.logger.debug('adding-pon-port-to-agent',
2042 type=self._pon.get_port().type,
2043 admin_state=self._pon.get_port().admin_state,
2044 oper_status=self._pon.get_port().oper_status,
2045 )
2046 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002047 if !dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302048 logger.Infow(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002049 var ponPortNo uint32 = 1
2050 if dh.ponPortNumber != 0 {
2051 ponPortNo = dh.ponPortNumber
2052 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002053
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002054 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002055 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002056 PortNo: ponPortNo,
2057 Label: fmt.Sprintf("pon-%d", ponPortNo),
2058 Type: voltha.Port_PON_ONU,
2059 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05302060 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002061 PortNo: ponPortNo}}, // Peer port is parent's port number
2062 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002063 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002064 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002065 e.Cancel(err)
2066 return
2067 }
2068 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302069 logger.Infow(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002070 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002071 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002072}
2073
2074// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00002075func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002076
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002077 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002078 var err error
2079 /*
2080 dh.Client = oop.NewOpenoltClient(dh.clientCon)
2081 dh.pTransitionMap.Handle(ctx, GrpcConnected)
2082 return nil
2083 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002084 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002085 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002086 e.Cancel(err)
2087 return
2088 }
2089
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002090 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002091 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002092 // reconcilement will be continued after mib download is done
2093 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002094
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002095 /*
2096 ############################################################################
2097 # Setup Alarm handler
2098 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
2099 device.serial_number)
2100 ############################################################################
2101 # Setup PM configuration for this device
2102 # Pass in ONU specific options
2103 kwargs = {
2104 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
2105 'heartbeat': self.heartbeat,
2106 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
2107 }
2108 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
2109 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
2110 self.logical_device_id, device.serial_number,
2111 grouped=True, freq_override=False, **kwargs)
2112 pm_config = self._pm_metrics.make_proto()
2113 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
2114 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
2115 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
2116
2117 # Note, ONU ID and UNI intf set in add_uni_port method
2118 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
2119 ani_ports=[self._pon])
2120
2121 # Code to Run OMCI Test Action
2122 kwargs_omci_test_action = {
2123 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2124 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2125 }
2126 serial_number = device.serial_number
2127 self._test_request = OmciTestRequest(self.core_proxy,
2128 self.omci_agent, self.device_id,
2129 AniG, serial_number,
2130 self.logical_device_id,
2131 exclusive=False,
2132 **kwargs_omci_test_action)
2133
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002134 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002135 else:
2136 self.logger.info('onu-already-activated')
2137 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08002138
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002139 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002140}
2141
2142// doStateConnected get the device info and update to voltha core
2143// for comparison of the original method (not that easy to uncomment): compare here:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302144//
2145// voltha-openolt-adapter/adaptercore/device_handler.go
2146// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00002147func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002148
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002149 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302150 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002151 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002152 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002153}
2154
2155// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00002156func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002157
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002158 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302159 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002160 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002161 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002162
2163 /*
2164 // Synchronous call to update device state - this method is run in its own go routine
2165 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
2166 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002167 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 +00002168 return err
2169 }
2170 return nil
2171 */
2172}
2173
2174// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00002175func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002176
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002177 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002178 var err error
2179
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002180 device := dh.device
2181 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002182 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002183 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002184 e.Cancel(err)
2185 return
2186 }
2187
2188 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002189 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002190 /*
2191 // Update the all ports state on that device to disable
2192 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002193 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002194 return er
2195 }
2196
2197 //Update the device oper state and connection status
2198 cloned.OperStatus = voltha.OperStatus_UNKNOWN
2199 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
2200 dh.device = cloned
2201
2202 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002203 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002204 return er
2205 }
2206
2207 //get the child device for the parent device
2208 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
2209 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002210 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002211 return err
2212 }
2213 for _, onuDevice := range onuDevices.Items {
2214
2215 // Update onu state as down in onu adapter
2216 onuInd := oop.OnuIndication{}
2217 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04002218 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002219 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
2220 if er != nil {
2221 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00002222 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002223 //Do not return here and continue to process other ONUs
2224 }
2225 }
2226 // * Discovered ONUs entries need to be cleared , since after OLT
2227 // is up, it starts sending discovery indications again* /
2228 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00002229 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002230 return nil
2231 */
Himani Chawla4d908332020-08-31 12:30:20 +05302232 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002233 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002234 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002235}
2236
Himani Chawla6d2ae152020-09-02 13:11:20 +05302237// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002238// #################################################################################
2239
2240// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05302241// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002242
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302243// GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002244func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00002245 dh.lockDevice.RLock()
2246 pOnuDeviceEntry := dh.pOnuOmciDevice
2247 if aWait && pOnuDeviceEntry == nil {
2248 //keep the read sema short to allow for subsequent write
2249 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002250 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002251 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
2252 // so it might be needed to wait here for that event with some timeout
2253 select {
2254 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002255 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002256 return nil
2257 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002258 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002259 // if written now, we can return the written value without sema
2260 return dh.pOnuOmciDevice
2261 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002262 }
mpagenko3af1f032020-06-10 08:53:41 +00002263 dh.lockDevice.RUnlock()
2264 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002265}
2266
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302267// setDeviceHandlerEntries sets the ONU device entry within the handler
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002268func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
2269 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002270 dh.lockDevice.Lock()
2271 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00002272 dh.pOnuOmciDevice = apDeviceEntry
2273 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08002274 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05302275 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002276 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002277}
2278
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302279// addOnuDeviceEntry creates a new ONU device or returns the existing
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302280//
2281//nolint:unparam
Himani Chawla6d2ae152020-09-02 13:11:20 +05302282func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002283 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002284
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002285 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002286 if deviceEntry == nil {
2287 /* costum_me_map in python code seems always to be None,
2288 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
2289 /* also no 'clock' argument - usage open ...*/
2290 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002291 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
2292 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
2293 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
2294 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
2295 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002296 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002297 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00002298 // fire deviceEntry ready event to spread to possibly waiting processing
2299 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002300 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002301 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002302 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002303 }
2304 // might be updated with some error handling !!!
2305 return nil
2306}
2307
dbainbri4d3a0dc2020-12-02 00:33:42 +00002308func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002309 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002310 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
2311
2312 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002313
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002314 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002315 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002316 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2317 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002318 }
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302319
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002320 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002321 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002322 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002323
khenaidoo42dcdfd2021-10-19 17:34:12 -04002324 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002325 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002326 OperStatus: voltha.OperStatus_ACTIVATING,
2327 ConnStatus: voltha.ConnectStatus_REACHABLE,
2328 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002329 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002330 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302331 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
2332 }
2333 // On onu reboot, we have to perform mib-reset and persist the reboot state for reconciling scenario
2334 if dh.GetDeviceTechProfOnReboot() {
2335 pDevEntry.MutexPersOnuConfig.Lock()
2336 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2337 pDevEntry.SOnuPersistentData.PersRebootInProgress = true
akashreddykb03dde02025-12-02 10:53:18 +05302338 pDevEntry.SOnuPersistentData.PersUniUnlockDone = false
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302339 pDevEntry.MutexPersOnuConfig.Unlock()
2340 }
2341 // Moving the previous call to write to KV store here, to store the ONU pers data after the update.
2342 if err := dh.StorePersistentData(ctx); err != nil {
2343 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2344 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002345 }
2346 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302347 logger.Info(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002348 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002349
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002350 pDevEntry.MutexPersOnuConfig.RLock()
2351 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
2352 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002353 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 +00002354 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00002355 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302356
2357 //VOL-4965: Recover previously Activating ONU during reconciliation.
2358 if dh.device.OperStatus == common.OperStatus_ACTIVATING {
2359 logger.Debugw(ctx, "Reconciling an ONU in previously activating state, perform MIB reset and resume normal start up",
2360 log.Fields{"device-id": dh.DeviceID})
2361 pDevEntry.MutexPersOnuConfig.Lock()
2362 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2363 pDevEntry.MutexPersOnuConfig.Unlock()
2364 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002365 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002366 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002367 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002368 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002369 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
2370 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
2371 // 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 +00002372 // 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 +00002373 // so let's just try to keep it simple ...
2374 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00002375 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002376 if err != nil || device == nil {
2377 //TODO: needs to handle error scenarios
2378 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
2379 return errors.New("Voltha Device not found")
2380 }
2381 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002382
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002383 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002384 return err
mpagenko3af1f032020-06-10 08:53:41 +00002385 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002386 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302387 if !dh.IsReconciling() && !dh.GetSkipOnuConfigEnabled() {
2388 /* this might be a good time for Omci Verify message? */
2389 verifyExec := make(chan bool)
2390 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
2391 dh.device.Id, pDevEntry.PDevOmciCC, false,
2392 true, true) //exclusive and allowFailure (anyway not yet checked)
2393 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002394
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302395 /* give the handler some time here to wait for the OMCi verification result
2396 after Timeout start and try MibUpload FSM anyway
2397 (to prevent stopping on just not supported OMCI verification from ONU) */
2398 select {
2399 case <-time.After(((cmn.CDefaultRetries+1)*otst.CTestRequestOmciTimeout + 1) * time.Second):
2400 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
2401 case testresult := <-verifyExec:
2402 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
2403 case <-dh.deviceDeleteCommChan:
2404 logger.Warnw(ctx, "Deleting device, stopping the omci test activity", log.Fields{"device-id": dh.DeviceID})
2405 return nil
2406 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002407 }
2408
2409 /* In py code it looks earlier (on activate ..)
2410 # Code to Run OMCI Test Action
2411 kwargs_omci_test_action = {
2412 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2413 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2414 }
2415 serial_number = device.serial_number
2416 self._test_request = OmciTestRequest(self.core_proxy,
2417 self.omci_agent, self.device_id,
2418 AniG, serial_number,
2419 self.logical_device_id,
2420 exclusive=False,
2421 **kwargs_omci_test_action)
2422 ...
2423 # Start test requests after a brief pause
2424 if not self._test_request_started:
2425 self._test_request_started = True
2426 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2427 reactor.callLater(tststart, self._test_request.start_collector)
2428
2429 */
2430 /* which is then: in omci_test_request.py : */
2431 /*
2432 def start_collector(self, callback=None):
2433 """
2434 Start the collection loop for an adapter if the frequency > 0
2435
2436 :param callback: (callable) Function to call to collect PM data
2437 """
2438 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2439 if callback is None:
2440 callback = self.perform_test_omci
2441
2442 if self.lc is None:
2443 self.lc = LoopingCall(callback)
2444
2445 if self.default_freq > 0:
2446 self.lc.start(interval=self.default_freq / 10)
2447
2448 def perform_test_omci(self):
2449 """
2450 Perform the initial test request
2451 """
2452 ani_g_entities = self._device.configuration.ani_g_entities
2453 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2454 is not None else None
2455 self._entity_id = ani_g_entities_ids[0]
2456 self.logger.info('perform-test', entity_class=self._entity_class,
2457 entity_id=self._entity_id)
2458 try:
2459 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2460 result = yield self._device.omci_cc.send(frame)
2461 if not result.fields['omci_message'].fields['success_code']:
2462 self.logger.info('Self-Test Submitted Successfully',
2463 code=result.fields[
2464 'omci_message'].fields['success_code'])
2465 else:
2466 raise TestFailure('Test Failure: {}'.format(
2467 result.fields['omci_message'].fields['success_code']))
2468 except TimeoutError as e:
2469 self.deferred.errback(failure.Failure(e))
2470
2471 except Exception as e:
2472 self.logger.exception('perform-test-Error', e=e,
2473 class_id=self._entity_class,
2474 entity_id=self._entity_id)
2475 self.deferred.errback(failure.Failure(e))
2476
2477 */
2478
2479 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002480 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002481
mpagenko1cc3cb42020-07-27 15:24:38 +00002482 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2483 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2484 * 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 +05302485 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002486 */
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302487
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002488 //call MibUploadFSM - transition up to state UlStInSync
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302489 // Breaking this part of code due to sca complexity
2490 err := dh.CheckAndStartMibUploadFsm(ctx, pDevEntry)
2491 return err
2492}
2493
2494func (dh *deviceHandler) CheckAndStartMibUploadFsm(ctx context.Context, pDevEntry *mib.OnuDeviceEntry) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002495 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002496 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002497 if pMibUlFsm.Is(mib.UlStDisabled) {
2498 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2499 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2500 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302501 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002502 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302503 //Determine ONU status and start/re-start MIB Synchronization tasks
2504 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002505 if pDevEntry.IsNewOnu() {
2506 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2507 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2508 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002509 }
Himani Chawla4d908332020-08-31 12:30:20 +05302510 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002511 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2512 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2513 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302514 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002515 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002516 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002517 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002518 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002519 "device-id": dh.DeviceID})
2520 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002521 }
2522 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002523 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2524 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002525 }
2526 return nil
2527}
2528
Holger Hildebrandt68854a82022-09-05 07:00:21 +00002529func (dh *deviceHandler) UpdateInterface(ctx context.Context) error {
mpagenko3af1f032020-06-10 08:53:41 +00002530 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002531 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002532 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302533 logger.Info(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002534
mpagenko900ee4b2020-10-12 11:56:34 +00002535 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2536 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2537 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002538 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002539 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002540 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002541 // abort: system behavior is just unstable ...
2542 return err
2543 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002544 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302545 if !dh.GetDeviceTechProfOnReboot() {
2546 _ = dh.deleteDevicePersistencyData(ctx) //ignore possible errors here and continue, hope is that data is synchronized with new ONU-Up
2547 }
mpagenko900ee4b2020-10-12 11:56:34 +00002548
2549 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002550 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002551 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002552 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002553 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2554 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002555 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002556 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002557
2558 //TODO!!! remove existing traffic profiles
2559 /* from py code, if TP's exist, remove them - not yet implemented
2560 self._tp = dict()
2561 # Let TP download happen again
2562 for uni_id in self._tp_service_specific_task:
2563 self._tp_service_specific_task[uni_id].clear()
2564 for uni_id in self._tech_profile_download_done:
2565 self._tech_profile_download_done[uni_id].clear()
2566 */
2567
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002568 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002569
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002570 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002571
mpagenkoe4782082021-11-25 12:04:26 +00002572 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002573 // abort: system behavior is just unstable ...
2574 return err
2575 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002576 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002577 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002578 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002579 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002580 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2581 OperStatus: voltha.OperStatus_DISCOVERED,
2582 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002583 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002584 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002585 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002586 // abort: system behavior is just unstable ...
2587 return err
2588 }
akashreddykb03dde02025-12-02 10:53:18 +05302589 if dh.GetDeviceTechProfOnReboot() {
2590 logger.Debugw(ctx, "Storing OnuPersData during device-down-indication", log.Fields{"device": dh.DeviceID, "onu-pers-data": dh.pOnuOmciDevice.SOnuPersistentData})
2591 if err := dh.StorePersistentData(ctx); err != nil {
2592 logger.Warnw(ctx, "store persistent data error - Failed to store DownIndication",
2593 log.Fields{"device-id": dh.DeviceID, "err": err})
2594 }
2595 }
mpagenko3af1f032020-06-10 08:53:41 +00002596 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002597 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002598 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002599 return nil
2600}
2601
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002602func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002603 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2604 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2605 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2606 // and using the stop/reset event should never harm
Holger Hildebrandt12609a12022-03-25 13:23:25 +00002607 logger.Debugw(ctx, "resetFsms entered", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002608
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002609 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Praneeth Kumar Nalmasfcdd20b2024-01-24 22:26:39 +05302610 //VOL-5260: During race conditions when adoptDevice has not yet completed
2611 // and deleteDevice is issued , returning error will further prevent clean up
2612 // at rwcore . Returning success for clean up to happen and discovery to happen again.
mpagenko900ee4b2020-10-12 11:56:34 +00002613 if pDevEntry == nil {
mgoudaa797e1c2025-06-24 17:49:42 +05302614 errMsg := fmt.Sprintf("Device entry is not found %s", dh.DeviceID)
2615 logger.Error(ctx, errMsg)
2616 return status.Error(codes.NotFound, errMsg)
mpagenko900ee4b2020-10-12 11:56:34 +00002617 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002618 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002619 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002620 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002621 pDevEntry.MutexOnuImageStatus.RLock()
2622 if pDevEntry.POnuImageStatus != nil {
2623 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002624 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002625 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002626
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002627 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002628 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002629 }
2630 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002631 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002632 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002633 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002634 }
mpagenko101ac942021-11-16 15:01:29 +00002635 //stop any deviceHandler reconcile processing (if running)
2636 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002637 //port lock/unlock FSM's may be active
2638 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002639 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002640 }
2641 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002642 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002643 }
2644 //techProfile related PonAniConfigFsm FSM may be active
2645 if dh.pOnuTP != nil {
2646 // should always be the case here
2647 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002648 if dh.pOnuTP.PAniConfigFsm != nil {
2649 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2650 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002651 }
mpagenko900ee4b2020-10-12 11:56:34 +00002652 }
2653 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002654 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002655 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002656 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002657 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002658 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002659 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002660 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002661 } else {
2662 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002663 }
2664 }
2665 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302666
2667 dh.mutexCollectorFlag.Lock()
2668 logger.Debugw(ctx, "check-collector-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.collectorIsRunning})
2669 if dh.collectorIsRunning {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002670 // Stop collector routine
2671 dh.stopCollector <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302672 dh.collectorIsRunning = false
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002673 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302674 dh.mutexCollectorFlag.Unlock()
2675
2676 dh.mutextAlarmManagerFlag.Lock()
2677 logger.Debugw(ctx, "check-alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
2678 if dh.alarmManagerIsRunning {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302679 dh.stopAlarmManager <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302680 dh.alarmManagerIsRunning = false
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302681 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302682 dh.mutextAlarmManagerFlag.Unlock()
2683
2684 dh.pSelfTestHdlr.SelfTestHandlerLock.Lock()
2685 logger.Debugw(ctx, "check-self-test-control-block-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.pSelfTestHdlr.SelfTestHandlerActive})
2686 if dh.pSelfTestHdlr.SelfTestHandlerActive {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002687 dh.pSelfTestHdlr.StopSelfTestModule <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302688 dh.pSelfTestHdlr.SelfTestHandlerActive = false
Girish Gowdra10123c02021-08-30 11:52:06 -07002689 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302690 dh.pSelfTestHdlr.SelfTestHandlerLock.Unlock()
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302691
Girish Gowdrae95687a2021-09-08 16:30:58 -07002692 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2693
mpagenko80622a52021-02-09 16:53:23 +00002694 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002695 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002696 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002697 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002698 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002699 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002700 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002701 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2702 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2703 // (even though it may also run into direct cancellation, a bit hard to verify here)
2704 // so don't set 'dh.upgradeCanceled = true' here!
2705 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2706 }
mpagenko38662d02021-08-11 09:45:19 +00002707 }
mpagenko80622a52021-02-09 16:53:23 +00002708
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002709 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002710 return nil
2711}
2712
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302713//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002714func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2715 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 +05302716
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002717 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002718 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002719 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002720 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002721 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002722 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002723 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002724
mpagenkoa40e99a2020-11-17 13:50:39 +00002725 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2726 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2727 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2728 * disable/enable toggling here to allow traffic
2729 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2730 * like the py comment says:
2731 * # start by locking all the unis till mib sync and initial mib is downloaded
2732 * # this way we can capture the port down/up events when we are ready
2733 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302734
mpagenkoa40e99a2020-11-17 13:50:39 +00002735 // Init Uni Ports to Admin locked state
2736 // *** should generate UniLockStateDone event *****
2737 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002738 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002739 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002740 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002741 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002742 }
2743}
2744
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302745//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002746func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2747 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302748 /* Mib download procedure -
2749 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2750 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002751 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002752 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002753 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002754 return
2755 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002756 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302757 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002758 if pMibDlFsm.Is(mib.DlStDisabled) {
2759 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2760 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 +05302761 // maybe try a FSM reset and then again ... - TODO!!!
2762 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002763 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302764 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002765 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2766 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302767 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002768 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302769 //Begin MIB data download (running autonomously)
2770 }
2771 }
2772 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002773 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002774 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302775 // maybe try a FSM reset and then again ... - TODO!!!
2776 }
2777 /***** Mib download started */
2778 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002779 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302780 }
2781}
2782
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302783//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002784func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302785 logger.Info(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002786 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
2787 if pDevEntry == nil {
2788 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2789 return
2790 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002791 if !dh.IsReconciling() {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002792 logger.Debugw(ctx, "call DeviceUpdate and DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002793 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002794 // update device info in core
2795 pDevEntry.MutexPersOnuConfig.RLock()
2796 dh.device.Vendor = pDevEntry.SOnuPersistentData.PersVendorID
2797 dh.device.VendorId = pDevEntry.SOnuPersistentData.PersVendorID
2798 dh.device.Model = pDevEntry.SOnuPersistentData.PersVersion
2799 pDevEntry.MutexPersOnuConfig.RUnlock()
2800 dh.logicalDeviceID = dh.DeviceID
2801 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
2802 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2803 }
2804 // update device state in core
mpagenko15ff4a52021-03-02 10:09:20 +00002805 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2806 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2807 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2808 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002809 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002810 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002811 ConnStatus: voltha.ConnectStatus_REACHABLE,
2812 OperStatus: voltha.OperStatus_ACTIVE,
2813 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302814 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002815 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302816 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002817 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302818 }
2819 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302820 logger.Info(ctx, "reconciling - don't notify core about updated device info and DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002821 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302822 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002823 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002824
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002825 if !dh.GetCollectorIsRunning() {
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002826 var waitForOmciProcessor sync.WaitGroup
2827 waitForOmciProcessor.Add(1)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002828 // Start PM collector routine
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002829 go dh.StartCollector(ctx, &waitForOmciProcessor)
2830 waitForOmciProcessor.Wait()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002831 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002832 if !dh.GetAlarmManagerIsRunning(ctx) {
2833 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002834 }
2835
Girish Gowdrae95687a2021-09-08 16:30:58 -07002836 // Start flow handler routines per UNI
2837 for _, uniPort := range dh.uniEntityMap {
2838 // only if this port was enabled for use by the operator at startup
2839 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2840 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2841 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2842 }
2843 }
2844 }
2845
Girish Gowdrae0140f02021-02-02 16:55:09 -08002846 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002847 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002848 // There is no way we should be landing here, but if we do then
2849 // there is nothing much we can do about this other than log error
2850 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2851 }
2852
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002853 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002854
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002855 pDevEntry.MutexPersOnuConfig.RLock()
2856 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2857 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302858 logger.Warn(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002859 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002860 dh.mutexForDisableDeviceRequested.Lock()
2861 dh.disableDeviceRequested = true
2862 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002863 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002864 // reconcilement will be continued after ani config is done
2865 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002866 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002867 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002868 dh.mutexForDisableDeviceRequested.RLock()
2869 if !dh.disableDeviceRequested {
2870 if dh.pUnlockStateFsm == nil {
2871 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2872 } else { //UnlockStateFSM already init
2873 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2874 dh.runUniLockFsm(ctx, false)
2875 }
2876 dh.mutexForDisableDeviceRequested.RUnlock()
2877 } else {
2878 dh.mutexForDisableDeviceRequested.RUnlock()
2879 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002880 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302881 }
2882}
2883
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302884//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002885func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2886 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302887
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002888 if !dh.IsReconciling() {
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302889 // Check if TPs are available post device reboot. If TPs are available start processing them and configure flows
2890 if dh.GetDeviceTechProfOnReboot() {
2891 if dh.CheckForDeviceTechProf(ctx) {
2892 go dh.DeviceFlowConfigOnReboot(ctx)
2893 }
2894 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002895 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002896 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002897 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2898 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002899 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002900 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002901 return
2902 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002903 pDevEntry.MutexPersOnuConfig.Lock()
2904 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2905 pDevEntry.MutexPersOnuConfig.Unlock()
2906 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002907 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002908 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002909 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302910 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302911 logger.Info(ctx, "reconciling - don't notify core that onu went to active but trigger tech profile config",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002912 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002913 dh.ReconcileDeviceTechProf(ctx)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302914
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002915 // reconcilement will be continued after ani config is done
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302916
Himani Chawla26e555c2020-08-31 12:30:20 +05302917 }
2918}
2919
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302920//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002921func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002922 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002923 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002924
mpagenko44bd8362021-11-15 11:40:05 +00002925 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002926 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002927 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002928 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002929 OperStatus: voltha.OperStatus_UNKNOWN,
2930 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002931 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002932 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002933 }
2934
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002935 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002936 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002937 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002938
2939 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002940 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002941
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002942 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002943 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002944 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002945 return
2946 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002947 pDevEntry.MutexPersOnuConfig.Lock()
2948 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2949 pDevEntry.MutexPersOnuConfig.Unlock()
2950 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002951 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002952 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002953 }
mpagenko900ee4b2020-10-12 11:56:34 +00002954}
2955
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302956//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002957func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002958 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002959 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002960 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002961 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002962 ConnStatus: voltha.ConnectStatus_REACHABLE,
2963 OperStatus: voltha.OperStatus_ACTIVE,
2964 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002965 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002966 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002967 }
2968
dbainbri4d3a0dc2020-12-02 00:33:42 +00002969 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002970 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002971 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002972 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002973
2974 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002975 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002976
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002977 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002978 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002979 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002980 return
2981 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002982 pDevEntry.MutexPersOnuConfig.Lock()
2983 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2984 pDevEntry.MutexPersOnuConfig.Unlock()
2985 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002986 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002987 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002988 }
mpagenko900ee4b2020-10-12 11:56:34 +00002989}
2990
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302991//nolint:unparam
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002992func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2993 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2994 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002995 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002996 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002997 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002998 OperStatus: voltha.OperStatus_FAILED,
2999 }); err != nil {
3000 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
3001 }
3002}
3003
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003004func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
3005 if devEvent == cmn.OmciAniConfigDone {
3006 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003007 // attention: the device reason update is done based on ONU-UNI-Port related activity
3008 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003009 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00003010 // which may be the case from some previous activity even on this UNI Port (but also other UNI ports)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00003011 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05303012 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003013 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00003014 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
3015 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
3016 dh.mutexReconcilingFirstPassFlag.Lock()
3017 if dh.reconcilingFirstPass {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303018 logger.Info(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00003019 dh.reconcilingFirstPass = false
3020 go dh.ReconcileDeviceFlowConfig(ctx)
3021 }
3022 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00003023 }
3024 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003025 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003026 // attention: the device reason update is done based on ONU-UNI-Port related activity
3027 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003028 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00003029 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
3030 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00003031 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003032 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303033}
3034
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003035func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003036 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003037 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05303038 // attention: the device reason update is done based on ONU-UNI-Port related activity
3039 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05303040
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003041 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
3042 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00003043 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00003044 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00003045 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00003046 }
3047 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003048 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00003049 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00003050 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003051 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303052 }
mpagenkof1fc3862021-02-16 10:09:52 +00003053
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003054 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00003055 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003056 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003057 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003058 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00003059 }
3060 } else {
3061 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003062 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003063 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303064}
3065
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303066// DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003067func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05303068 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003069 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003070 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003071 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003072 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003073 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00003074 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003075 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00003076 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003077 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003078 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003079 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003080 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003081 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003082 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003083 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003084 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003085 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00003086 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003087 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00003088 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003089 case cmn.UniEnableStateFailed:
3090 {
3091 dh.processUniEnableStateFailedEvent(ctx, devEvent)
3092 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003093 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00003094 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003095 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00003096 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003097 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00003098 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003099 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00003100 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003101 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00003102 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003103 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00003104 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003105 default:
3106 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003107 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003108 }
3109 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003110}
3111
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003112func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003113 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07003114 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05303115 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003116 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003117 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003118 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05303119 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003120 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003121 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003122 logger.Warnw(ctx, "OnuUniPort-add: Could not create Port", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003123 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003124 //store UniPort with the System-PortNumber key
3125 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003126 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003127 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003128 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003129 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003130 } //error logging already within UniPort method
3131 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303132 logger.Warn(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003133 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003134 }
3135 }
3136}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003137
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003138func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
3139 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003140 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003141 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003142 return
3143 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07003144 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003145 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003146 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
3147 for _, mgmtEntityID := range pptpInstKeys {
3148 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003149 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003150 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
3151 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003152 }
3153 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003154 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003155 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003156 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003157 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
3158 for _, mgmtEntityID := range veipInstKeys {
3159 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003160 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003161 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
3162 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003163 }
3164 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003165 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003166 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003167 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03003168 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
3169 for _, mgmtEntityID := range potsInstKeys {
3170 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003171 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003172 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
3173 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03003174 }
3175 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003176 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03003177 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07003178 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003179 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003180 return
3181 }
3182
mpagenko2c3f6c52021-11-23 11:22:10 +00003183 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
3184 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
3185 // also for the POTS ports, so we include them already for future usage - should anyway do no great harm
Girish Gowdrae95687a2021-09-08 16:30:58 -07003186 dh.flowCbChan = make([]chan FlowCb, uniCnt)
3187 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
3188 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00003189 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
3190 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303191 dh.chUniVlanConfigOnRebootDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003192 for i := 0; i < int(uniCnt); i++ {
3193 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00003194 dh.stopFlowMonitoringRoutine[i] = make(chan bool, 1)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003195 }
3196}
3197
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003198// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
3199func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003200 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05303201 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003202 // with following remark:
3203 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
3204 // # load on the core
3205
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003206 // 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 +00003207
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003208 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00003209 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003210 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
3211 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
mgoudad611f4c2025-10-30 14:49:27 +05303212 uniPort.SetOperState(common.OperStatus_ACTIVE)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003213 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003214 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003215 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04003216 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003217 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003218 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003219 PortNo: port.PortNo,
3220 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04003221 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003222 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 -04003223 }
3224 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003225 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303226 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003227 }
mpagenko3af1f032020-06-10 08:53:41 +00003228 }
3229 }
3230}
3231
3232// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003233func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
3234 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00003235 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
3236 for uniNo, uniPort := range dh.uniEntityMap {
3237 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02003238
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003239 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
3240 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
mgoudad611f4c2025-10-30 14:49:27 +05303241 uniPort.SetOperState(common.OperStatus_UNKNOWN)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003242 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003243 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003244 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04003245 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003246 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003247 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003248 PortNo: port.PortNo,
3249 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04003250 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003251 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 -04003252 }
3253 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003254 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303255 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003256 }
3257
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003258 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003259 }
3260}
3261
3262// ONU_Active/Inactive announcement on system KAFKA bus
3263// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
mgoudad611f4c2025-10-30 14:49:27 +05303264func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState common.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003265 var de voltha.DeviceEvent
3266 eventContext := make(map[string]string)
3267 //Populating event context
3268 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04003269 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003270 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003271 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003272 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00003273 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 +00003274 }
3275 oltSerialNumber := parentDevice.SerialNumber
3276
3277 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
3278 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
3279 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05303280 eventContext["olt-serial-number"] = oltSerialNumber
3281 eventContext["device-id"] = aDeviceID
3282 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03003283 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003284 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
3285 deviceEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00003286 eventContext["vendor-id"] = deviceEntry.SOnuPersistentData.PersVendorID
3287 eventContext["model"] = deviceEntry.SOnuPersistentData.PersVersion
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003288 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
3289 deviceEntry.MutexPersOnuConfig.RUnlock()
3290 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003291 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03003292 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
3293 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
3294 } else {
3295 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
3296 log.Fields{"device-id": aDeviceID})
3297 return
3298 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003299
3300 /* Populating device event body */
3301 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05303302 de.ResourceId = aDeviceID
3303 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003304 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
3305 de.Description = fmt.Sprintf("%s Event - %s - %s",
3306 cEventObjectType, cOnuActivatedEvent, "Raised")
3307 } else {
3308 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
3309 de.Description = fmt.Sprintf("%s Event - %s - %s",
3310 cEventObjectType, cOnuActivatedEvent, "Cleared")
3311 }
3312 /* Send event to KAFKA */
kesavand510a31c2022-03-16 17:12:12 +05303313 if err := dh.EventProxy.SendDeviceEventWithKey(ctx, &de, equipment, pon, raisedTs, aDeviceID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003314 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05303315 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003316 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303317 logger.Infow(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05303318 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003319}
3320
Himani Chawla4d908332020-08-31 12:30:20 +05303321// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003322func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303323 chLSFsm := make(chan cmn.Message, 2)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003324 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05303325 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003326 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003327 sFsmName = "LockStateFSM"
3328 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003329 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003330 sFsmName = "UnLockStateFSM"
3331 }
mpagenko3af1f032020-06-10 08:53:41 +00003332
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003333 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00003334 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003335 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00003336 return
3337 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003338 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003339 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05303340 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003341 dh.pLockStateFsm = pLSFsm
3342 } else {
3343 dh.pUnlockStateFsm = pLSFsm
3344 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003345 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003346 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003347 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003348 }
3349}
3350
3351// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00003352func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003353 /* Uni Port lock/unlock procedure -
3354 ***** should run via 'adminDone' state and generate the argument requested event *****
3355 */
3356 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05303357 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003358 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003359 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
3360 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003361 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
3362 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003363 }
3364 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003365 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003366 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
3367 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003368 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
3369 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003370 }
3371 }
3372 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003373 if pLSStatemachine.Is(uniprt.UniStDisabled) {
3374 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003375 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003376 // maybe try a FSM reset and then again ... - TODO!!!
3377 } else {
3378 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003379 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003380 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003381 }
3382 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003383 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003384 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003385 // maybe try a FSM reset and then again ... - TODO!!!
3386 }
3387 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003388 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003389 // maybe try a FSM reset and then again ... - TODO!!!
3390 }
3391}
3392
mpagenko80622a52021-02-09 16:53:23 +00003393// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00003394// precondition: lockUpgradeFsm is already locked from caller of this function
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303395//
3396//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003397func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303398 chUpgradeFsm := make(chan cmn.Message, 2)
mpagenko80622a52021-02-09 16:53:23 +00003399 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003400 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003401 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003402 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303403 return fmt.Errorf("no valid omciCC - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003404 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003405 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00003406 sFsmName, chUpgradeFsm)
3407 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003408 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00003409 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003410 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
3411 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003412 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00003413 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303414 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003415 }
mpagenko59862f02021-10-11 08:53:18 +00003416 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00003417 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
3418 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00003419 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
3420 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00003421 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003422 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003423 } else {
3424 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003425 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003426 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303427 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003428 }
3429 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003430 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003431 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303432 return fmt.Errorf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003433 }
3434 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003435 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303436 return fmt.Errorf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003437 }
3438 return nil
3439}
3440
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003441// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
3442func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00003443 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003444 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003445 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00003446 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
3447 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00003448 dh.pLastUpgradeImageState = apImageState
3449 dh.lockUpgradeFsm.Unlock()
3450 //signal upgradeFsm removed using non-blocking channel send
3451 select {
3452 case dh.upgradeFsmChan <- struct{}{}:
3453 default:
3454 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003455 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003456 }
mpagenko80622a52021-02-09 16:53:23 +00003457}
3458
mpagenko15ff4a52021-03-02 10:09:20 +00003459// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3460func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003461 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003462 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003463 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003464 return
3465 }
3466
3467 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003468 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003469 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003470 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3471 dh.lockUpgradeFsm.RUnlock()
3472 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3473 return
3474 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003475 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003476 if pUpgradeStatemachine != nil {
3477 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3478 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003479 UpgradeState := pUpgradeStatemachine.Current()
3480 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3481 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3482 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003483 // 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 +00003484 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003485 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3486 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003487 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003488 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003489 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003490 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3491 dh.upgradeCanceled = true
3492 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3493 }
mpagenko15ff4a52021-03-02 10:09:20 +00003494 return
3495 }
mpagenko59862f02021-10-11 08:53:18 +00003496 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003497 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3498 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003499 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003500 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003501 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3502 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003503 return
3504 }
3505 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003506 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003507 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003508 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3509 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003510 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3511 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003512 return
3513 }
3514 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003515 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003516 }
3517 } else {
3518 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 +00003519 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003520 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3521 dh.upgradeCanceled = true
3522 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3523 }
mpagenko1f8e8822021-06-25 14:10:21 +00003524 }
mpagenko15ff4a52021-03-02 10:09:20 +00003525 return
3526 }
mpagenko59862f02021-10-11 08:53:18 +00003527 dh.lockUpgradeFsm.RUnlock()
3528 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3529 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003530 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3531 dh.upgradeCanceled = true
3532 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3533 }
mpagenko59862f02021-10-11 08:53:18 +00003534 return
3535 }
3536 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3537 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3538 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3539 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3540 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3541 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3542 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003543 }
mpagenko15ff4a52021-03-02 10:09:20 +00003544 }
3545 }
3546 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003547 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003548 }
mpagenko59862f02021-10-11 08:53:18 +00003549 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003550}
3551
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303552// SetBackend provides a DB backend for the specified path on the existing KV client
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003553func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003554
3555 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003556 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003557 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003558 kvbackend := &db.Backend{
3559 Client: dh.pOpenOnuAc.kvClient,
3560 StoreType: dh.pOpenOnuAc.KVStoreType,
3561 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003562 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003563 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3564 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003565
mpagenkoaf801632020-07-03 10:00:42 +00003566 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003567}
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303568
3569//nolint:unparam
khenaidoo7d3c5582021-08-11 18:09:44 -04003570func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303571 loMatchPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003572
mpagenkodff5dda2020-08-28 11:52:01 +00003573 for _, field := range flow.GetOfbFields(apFlowItem) {
3574 switch field.Type {
3575 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3576 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003577 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003578 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3579 }
mpagenko01e726e2020-10-23 09:45:29 +00003580 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003581 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3582 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303583 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003584 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303585 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3586 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003587 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3588 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003589 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003590 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303591 return
mpagenkodff5dda2020-08-28 11:52:01 +00003592 }
3593 }
mpagenko01e726e2020-10-23 09:45:29 +00003594 */
mpagenkodff5dda2020-08-28 11:52:01 +00003595 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3596 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303597 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003598 loMatchVlanMask := uint16(field.GetVlanVidMask())
mgoudad611f4c2025-10-30 14:49:27 +05303599 if *loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) ||
3600 loMatchVlanMask != uint16(of.OfpVlanId_OFPVID_PRESENT) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303601 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003602 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003603 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303604 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003605 }
3606 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3607 {
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303608 *loMatchPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003609 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303610 "PCP": loMatchPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003611 }
3612 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3613 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003614 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003615 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3616 }
3617 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3618 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003619 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003620 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3621 }
3622 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3623 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003624 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003625 "IPv4-DST": field.GetIpv4Dst()})
3626 }
3627 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3628 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003629 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003630 "IPv4-SRC": field.GetIpv4Src()})
3631 }
3632 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3633 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003634 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003635 "Metadata": field.GetTableMetadata()})
3636 }
3637 /*
3638 default:
3639 {
3640 //all other entires ignored
3641 }
3642 */
3643 }
3644 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303645}
mpagenkodff5dda2020-08-28 11:52:01 +00003646
khenaidoo7d3c5582021-08-11 18:09:44 -04003647func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003648 for _, action := range flow.GetActions(apFlowItem) {
3649 switch action.Type {
3650 /* not used:
3651 case of.OfpActionType_OFPAT_OUTPUT:
3652 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003653 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003654 "Output": action.GetOutput()})
3655 }
3656 */
3657 case of.OfpActionType_OFPAT_PUSH_VLAN:
3658 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003659 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003660 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3661 }
3662 case of.OfpActionType_OFPAT_SET_FIELD:
3663 {
3664 pActionSetField := action.GetSetField()
3665 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003666 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003667 "OxcmClass": pActionSetField.Field.OxmClass})
3668 }
3669 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303670 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003671 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303672 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003673 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303674 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003675 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303676 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003677 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003678 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003679 "Type": pActionSetField.Field.GetOfbField().Type})
3680 }
3681 }
3682 /*
3683 default:
3684 {
3685 //all other entires ignored
3686 }
3687 */
3688 }
3689 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303690}
3691
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303692// addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003693func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003694 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
mgoudad611f4c2025-10-30 14:49:27 +05303695 var loSetVlan = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3696 var loMatchVlan = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303697 var loSetPcp uint8
3698 var loMatchPcp uint8 = 8 // could the const 'cPrioDoNotFilter' be used from omci_vlan_config.go ?
Himani Chawla26e555c2020-08-31 12:30:20 +05303699 var loIPProto uint32
3700 /* the TechProfileId is part of the flow Metadata - compare also comment within
3701 * OLT-Adapter:openolt_flowmgr.go
3702 * Metadata 8 bytes:
3703 * Most Significant 2 Bytes = Inner VLAN
3704 * Next 2 Bytes = Tech Profile ID(TPID)
3705 * Least Significant 4 Bytes = Port ID
3706 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3707 * subscriber related flows.
3708 */
3709
dbainbri4d3a0dc2020-12-02 00:33:42 +00003710 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303711 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003712 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003713 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003714 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303715 }
mpagenko551a4d42020-12-08 18:09:20 +00003716 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003717 loCookie := apFlowItem.GetCookie()
3718 loCookieSlice := []uint64{loCookie}
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303719 loInnerCvlan := flow.GetInnerTagFromWriteMetaData(ctx, metadata)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003720 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303721 "TechProf-Id": loTpID, "cookie": loCookie, "innerCvlan": loInnerCvlan})
Himani Chawla26e555c2020-08-31 12:30:20 +05303722
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303723 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loMatchPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003724 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303725 if loIPProto == 2 {
3726 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3727 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003728 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003729 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303730 return nil
3731 }
mpagenko01e726e2020-10-23 09:45:29 +00003732 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003733 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003734
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303735 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) && (loMatchPcp == 8) &&
3736 loInnerCvlan == uint16(of.OfpVlanId_OFPVID_NONE) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003737 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003738 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003739 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3740 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3741 //TODO!!: Use DeviceId within the error response to rwCore
3742 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003743 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003744 }
3745 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003746 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003747 loSetVlan = loMatchVlan //both 'transparent' (copy any)
Abhilash Laxmeshwarf15a0d02022-08-08 11:09:32 +05303748 } else if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) &&
3749 loInnerCvlan != uint16(of.OfpVlanId_OFPVID_NONE) {
3750 loSetVlan = loMatchVlan
3751 logger.Debugw(ctx, "flow-add, double tagged case, set setvlan to matchvlan ", log.Fields{"device-id": dh.DeviceID, "loSetVlan": loSetVlan, "loMatchVlan": loMatchVlan})
mpagenkodff5dda2020-08-28 11:52:01 +00003752 } else {
3753 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3754 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3755 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303756 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003757 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003758 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003759 }
mpagenko9a304ea2020-12-16 15:54:01 +00003760
khenaidoo42dcdfd2021-10-19 17:34:12 -04003761 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003762 if apFlowMetaData != nil {
3763 meter = apFlowMetaData.Meters[0]
3764 }
mpagenkobc4170a2021-08-17 16:42:10 +00003765 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3766 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3767 // when different rules are requested concurrently for the same uni
3768 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3769 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3770 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003771 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3772 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003773 //SetUniFlowParams() may block on some rule that is suspended-to-add
3774 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003775 // Also the error is returned to caller via response channel
3776 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303777 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, false, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003778 dh.lockVlanConfig.RUnlock()
3779 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003780 return
mpagenkodff5dda2020-08-28 11:52:01 +00003781 }
mpagenkobc4170a2021-08-17 16:42:10 +00003782 dh.lockVlanConfig.RUnlock()
3783 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003784 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303785 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, cmn.OmciVlanFilterAddDone, false, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003786 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003787 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003788 if err != nil {
3789 *respChan <- err
3790 }
mpagenko01e726e2020-10-23 09:45:29 +00003791}
3792
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303793// removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003794func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003795 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3796 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3797 //no extra check is done on the rule parameters
3798 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3799 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3800 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3801 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003802 // - 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 +00003803 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003804 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003805
3806 /* TT related temporary workaround - should not be needed anymore
3807 for _, field := range flow.GetOfbFields(apFlowItem) {
3808 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3809 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003810 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003811 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3812 if loIPProto == 2 {
3813 // 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 +00003814 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003815 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003816 return nil
3817 }
3818 }
3819 } //for all OfbFields
3820 */
3821
mpagenko9a304ea2020-12-16 15:54:01 +00003822 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003823 dh.lockVlanConfig.RLock()
3824 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003825 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3826 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003827 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3828 return
mpagenko01e726e2020-10-23 09:45:29 +00003829 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003830 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003831 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003832 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003833 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003834 // Push response on the response channel
3835 if respChan != nil {
3836 // 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
3837 select {
3838 case *respChan <- nil:
3839 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3840 default:
3841 }
3842 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003843 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003844}
3845
Himani Chawla26e555c2020-08-31 12:30:20 +05303846// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003847// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003848// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003849func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303850 aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, innerCvlan uint16, aDevEvent cmn.OnuDeviceEvent, lastFlowToReconcile bool, lastFlowToConfOnReboot bool, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303851 chVlanFilterFsm := make(chan cmn.Message, 2)
mpagenkodff5dda2020-08-28 11:52:01 +00003852
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003853 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003854 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003855 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3856 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003857 }
3858
Sridhar Ravindra2f86efb2024-12-06 11:02:10 +05303859 if dh.pDeviceStateFsm.Current() == devStDown {
3860 logger.Warnw(ctx, "UniVlanConfigFsm : aborting, device state down", log.Fields{"device-id": dh.DeviceID})
3861 return fmt.Errorf("device state down for device-id %x - aborting", dh.DeviceID)
3862 }
3863
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003864 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3865 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303866 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, lastFlowToReconcile, lastFlowToConfOnReboot, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003867 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003868 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3869 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003870 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3871 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003872 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003873 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3874 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003875 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3876 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003877 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003878 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303879 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003880 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003881 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3882 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003883 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003884 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003885 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3886 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003887 }
3888 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003889 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003890 "device-id": dh.DeviceID})
3891 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003892 }
3893 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003894 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003895 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3896 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003897 }
3898 return nil
3899}
3900
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303901// VerifyVlanConfigRequest checks on existence of a given uniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003902// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003903func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003904 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003905 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003906 for _, uniPort := range dh.uniEntityMap {
3907 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003908 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003909 pCurrentUniPort = uniPort
3910 break //found - end search loop
3911 }
3912 }
3913 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003914 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003915 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003916 return
3917 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003918 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003919}
3920
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303921// VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003922func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003923 //TODO!! verify and start pending flow configuration
3924 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3925 //but execution was set to 'on hold' as first the TechProfile config had to be applied
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303926 logger.Info(ctx, "Verifying UniVlanConfig Request", log.Fields{"device-id": dh.DeviceID, "UniPort": apUniPort.PortNo, "techprofile-id": aTpID})
mpagenkof1fc3862021-02-16 10:09:52 +00003927 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003928 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003929 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003930 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003931 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003932 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003933 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003934 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003935 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3936 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003937 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003938 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003939 } else {
3940 /***** UniVlanConfigFsm continued */
3941 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003942 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3943 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003944 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003945 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3946 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003947 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003948 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003949 } else {
3950 /***** UniVlanConfigFsm continued */
3951 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003952 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3953 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003954 }
mpagenkodff5dda2020-08-28 11:52:01 +00003955 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003956 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003957 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3958 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003959 }
3960 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003961 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 +00003962 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3963 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003964 }
3965 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003966 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003967 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003968 }
mpagenkof1fc3862021-02-16 10:09:52 +00003969 } else {
3970 dh.lockVlanConfig.RUnlock()
3971 }
mpagenkodff5dda2020-08-28 11:52:01 +00003972}
3973
Akash Soni3de0e062024-12-11 16:37:26 +05303974// handleAniConfigFSMFailure handles the failure of the ANI config FSM by resetting the VLAN filter FSM
3975func (dh *deviceHandler) HandleAniConfigFSMFailure(ctx context.Context, uniID uint8) {
3976 dh.lockVlanConfig.Lock()
3977 defer dh.lockVlanConfig.Unlock()
3978
3979 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniID]; exist {
3980 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
3981 if pVlanFilterStatemachine != nil {
3982 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
3983 logger.Warnw(ctx, "Failed to reset UniVlanConfigFsm", log.Fields{
3984 "err": err, "device-id": dh.DeviceID, "UniPort": uniID, "FsmState": pVlanFilterStatemachine.Current(),
3985 })
3986 } else {
3987 logger.Infow(ctx, "Successfully reset UniVlanConfigFsm", log.Fields{
3988 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID, "UniPort": uniID,
3989 })
3990 }
3991 } else {
3992 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no reset performed", log.Fields{
3993 "device-id": dh.DeviceID, "UniPort": uniID,
3994 })
3995 }
3996 } else {
3997 logger.Debugw(ctx, "No UniVlanConfigFsm found for the UNI ID", log.Fields{
3998 "device-id": dh.DeviceID, "UniPort": uniID,
3999 })
4000 }
4001}
4002
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304003// RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00004004// 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 +00004005func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00004006 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004007 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00004008 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00004009 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004010 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00004011 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00004012}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004013
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304014// startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004015func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00004016 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
4017 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
4018 // obviously then parallel processing on the cancel must be avoided
4019 // deadline context to ensure completion of background routines waited for
4020 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
4021 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
4022 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05304023 defer cancel() // Ensure cancel is called to release resources
mpagenkof1fc3862021-02-16 10:09:52 +00004024
Akash Soni840f8d62024-12-11 19:37:06 +05304025 err := aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
4026 if err != nil {
4027 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID})
4028 return err
4029 }
4030 return nil
mpagenkof1fc3862021-02-16 10:09:52 +00004031}
4032
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304033// StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
4034// available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004035func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
4036 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004037
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004038 if dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304039 logger.Info(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004040 return nil
4041 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004042 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004043
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004044 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004045 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004046 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
4047 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004048 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004049 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004050
mpagenkof1fc3862021-02-16 10:09:52 +00004051 if aWriteToKvStore {
4052 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
4053 }
4054 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004055}
4056
dbainbri4d3a0dc2020-12-02 00:33:42 +00004057func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004058 defer cancel() //ensure termination of context (may be pro forma)
4059 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00004060 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004061 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004062}
4063
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304064// ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
4065//
4066// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
mpagenkoe4782082021-11-25 12:04:26 +00004067func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
4068 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
4069 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
4070 dh.mutexDeviceReason.Lock()
4071 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004072 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004073 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04004074 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004075 DeviceId: dh.DeviceID,
4076 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04004077 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00004078 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004079 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004080 return err
4081 }
mpagenkoe4782082021-11-25 12:04:26 +00004082 } else {
4083 logger.Debugf(ctx, "update reason in core not requested: %s - device-id: %s", cmn.DeviceReasonMap[deviceReason], dh.DeviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004084 }
mpagenkoe4782082021-11-25 12:04:26 +00004085 dh.deviceReason = deviceReason
4086 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
4087 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004088 return nil
4089}
4090
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004091func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
4092 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004093 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004094 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4095 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004096 }
mpagenkof1fc3862021-02-16 10:09:52 +00004097 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004098}
4099
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05304100func (dh *deviceHandler) UpdateRebootPersData(ctx context.Context, flag bool) {
4101 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
4102 if pDevEntry != nil {
4103 pDevEntry.MutexPersOnuConfig.Lock()
4104 pDevEntry.SOnuPersistentData.PersRebootInProgress = flag
4105 pDevEntry.MutexPersOnuConfig.Unlock()
4106 } else {
4107 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4108 }
4109}
4110
4111func (dh *deviceHandler) GetPersRebootFlag(ctx context.Context) bool {
4112 rebootFlag := false
4113 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
4114 if pDevEntry != nil {
4115 pDevEntry.MutexPersOnuConfig.RLock()
4116 rebootFlag = pDevEntry.SOnuPersistentData.PersRebootInProgress
4117 pDevEntry.MutexPersOnuConfig.RUnlock()
4118 } else {
4119 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4120 }
4121 return rebootFlag
4122}
4123
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004124// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03004125// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004126func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
4127 dh.lockDevice.RLock()
4128 defer dh.lockDevice.RUnlock()
4129 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004130 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004131 }
4132 return 0, errors.New("error-fetching-uni-port")
4133}
Girish Gowdrae09a6202021-01-12 18:10:59 -08004134
4135// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004136func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4137 var errorsList []error
4138 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 -08004139
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004140 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
4141 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
4142 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
4143
4144 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
4145 // successfully.
4146 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
4147 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
4148 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004149 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 -08004150 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08004151 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004152 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004153 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08004154}
4155
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004156func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4157 var err error
4158 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004159 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004160
4161 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004162 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004163 errorsList = append(errorsList, err)
4164 }
4165 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004166 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00004167
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004168 return errorsList
4169}
4170
4171func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4172 var err error
4173 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004174 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004175 // Check if group metric related config is updated
4176 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004177 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
4178 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
4179 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004180
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004181 if ok && m.Frequency != v.GroupFreq {
4182 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004183 errorsList = append(errorsList, err)
4184 }
4185 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004186 if ok && m.Enabled != v.Enabled {
4187 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004188 errorsList = append(errorsList, err)
4189 }
4190 }
4191 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004192 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004193 return errorsList
4194}
4195
4196func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4197 var err error
4198 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004199 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004200 // Check if standalone metric related config is updated
4201 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004202 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
4203 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
4204 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004205
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004206 if ok && m.Frequency != v.SampleFreq {
4207 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004208 errorsList = append(errorsList, err)
4209 }
4210 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004211 if ok && m.Enabled != v.Enabled {
4212 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004213 errorsList = append(errorsList, err)
4214 }
4215 }
4216 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004217 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004218 return errorsList
4219}
4220
4221// nolint: gocyclo
Girish Gowdraf7d82d02022-04-26 16:18:35 -07004222func (dh *deviceHandler) StartCollector(ctx context.Context, waitForOmciProcessor *sync.WaitGroup) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004223 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
bseeniva596a5222026-01-23 19:26:11 +05304224 dh.RLockMutexDeletionInProgressFlag()
4225 if dh.GetDeletionInProgress() {
4226 logger.Warnw(ctx, "Device deletion in progress - avoid starting metrics collector routine", log.Fields{"device-id": dh.device.Id})
4227 dh.RUnlockMutexDeletionInProgressFlag()
4228 return
4229 }
4230 // Set collectorIsRunning flag to true while still holding deviceDeletionFlag lock,
4231 // to avoid potential race condition where resetFsm from DeleteDevice might avoid stopping the collector routine if this flag is not yet set
4232 dh.setCollectorIsRunning(true)
4233 dh.RUnlockMutexDeletionInProgressFlag()
Girish Gowdrae09a6202021-01-12 18:10:59 -08004234
4235 // Start routine to process OMCI GET Responses
Girish Gowdraf7d82d02022-04-26 16:18:35 -07004236 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx, waitForOmciProcessor)
Himani Chawla43f95ff2021-06-03 00:24:12 +05304237 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004238 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004239 // Initialize the next metric collection time.
4240 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
4241 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004242 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
praneeth nalmas808f43a2023-05-14 12:54:34 +05304243 statsCollectionticker := time.NewTicker((pmmgr.FrequencyGranularity) * time.Second)
4244 defer statsCollectionticker.Stop()
Girish Gowdrae09a6202021-01-12 18:10:59 -08004245 for {
praneeth nalmas808f43a2023-05-14 12:54:34 +05304246
Girish Gowdrae09a6202021-01-12 18:10:59 -08004247 select {
4248 case <-dh.stopCollector:
4249 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004250 // Stop the L2 PM FSM
4251 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004252 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
4253 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
4254 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004255 }
4256 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004257 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004258 }
4259 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004260 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
4261 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07004262 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004263 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
4264 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07004265 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08004266
Girish Gowdrae09a6202021-01-12 18:10:59 -08004267 return
praneeth nalmas808f43a2023-05-14 12:54:34 +05304268 case <-statsCollectionticker.C: // Check every FrequencyGranularity to see if it is time for collecting metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004269 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
4270 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
4271 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
4272 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08004273 // Update the next metric collection time.
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004274 prevInternal := dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime
4275 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = prevInternal.Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004276 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004277 } else {
4278 if dh.pmConfigs.Grouped { // metrics are managed as a group
4279 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004280 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08004281
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004282 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
4283 // 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 -08004284 // 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 +00004285 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
4286 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004287 }
4288 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004289 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
4290 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
4291 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
4292 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004293 }
4294 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004295 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004296
4297 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004298 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
4299 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
4300 // 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 -08004301 // 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 +00004302 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004303 prevInternal := g.NextCollectionInterval
4304 g.NextCollectionInterval = prevInternal.Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004305 }
4306 }
4307 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004308 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
4309 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
4310 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004311 prevInternal := m.NextCollectionInterval
4312 m.NextCollectionInterval = prevInternal.Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004313 }
4314 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004315 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004316 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04004317 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004318 } */
4319 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08004320 }
4321 }
4322}
kesavandfdf77632021-01-26 23:40:33 -05004323
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304324//nolint:unparam
Akash Soni3c176c62024-12-04 13:30:43 +05304325func (dh *deviceHandler) setOnuOffloadStats(ctx context.Context, config *extension.AppOffloadOnuConfig) *extension.SingleSetValueResponse {
4326
4327 singleValResp := extension.SingleSetValueResponse{
4328 Response: &extension.SetValueResponse{
4329 Status: extension.SetValueResponse_OK,
4330 },
4331 }
4332
4333 return &singleValResp
4334}
4335
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004336func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05004337
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004338 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
4339 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05004340}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004341
Himani Chawla43f95ff2021-06-03 00:24:12 +05304342func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
4343 if dh.pOnuMetricsMgr == nil {
4344 return &extension.SingleGetValueResponse{
4345 Response: &extension.GetValueResponse{
4346 Status: extension.GetValueResponse_ERROR,
4347 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
4348 },
4349 }
4350 }
Himani Chawlaee10b542021-09-20 16:46:40 +05304351 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05304352 return resp
4353}
4354
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +00004355func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
4356
4357 var err error
4358 var pDevOmciCC *cmn.OmciCC
4359 if dh.pOnuOmciDevice == nil {
4360 logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
4361 err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
4362 } else {
4363 pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
4364 if pDevOmciCC == nil {
4365 logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
4366 err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
4367 }
4368 }
4369 if err != nil {
4370 return &extension.SingleGetValueResponse{
4371 Response: &extension.GetValueResponse{
4372 Status: extension.GetValueResponse_ERROR,
4373 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
4374 },
4375 },
4376 err
4377 }
4378 return pDevOmciCC.GetOmciCounters(), nil
4379}
4380
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304381//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004382func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
4383 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00004384 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004385 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004386 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004387}
4388
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004389func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00004390 var pAdapterFsm *cmn.AdapterFsm
4391 //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 +00004392 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004393 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004394 {
mpagenkofbf577d2021-10-12 11:44:33 +00004395 if dh.pOnuOmciDevice != nil {
4396 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
4397 } else {
4398 return true //FSM not active - so there is no activity on omci
4399 }
mpagenkof1fc3862021-02-16 10:09:52 +00004400 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004401 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004402 {
mpagenkofbf577d2021-10-12 11:44:33 +00004403 if dh.pOnuOmciDevice != nil {
4404 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
4405 } else {
4406 return true //FSM not active - so there is no activity on omci
4407 }
mpagenkof1fc3862021-02-16 10:09:52 +00004408 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004409 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004410 {
mpagenkofbf577d2021-10-12 11:44:33 +00004411 if dh.pLockStateFsm != nil {
4412 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
4413 } else {
4414 return true //FSM not active - so there is no activity on omci
4415 }
mpagenkof1fc3862021-02-16 10:09:52 +00004416 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004417 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004418 {
mpagenkofbf577d2021-10-12 11:44:33 +00004419 if dh.pUnlockStateFsm != nil {
4420 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
4421 } else {
4422 return true //FSM not active - so there is no activity on omci
4423 }
mpagenkof1fc3862021-02-16 10:09:52 +00004424 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004425 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004426 {
mpagenkofbf577d2021-10-12 11:44:33 +00004427 if dh.pOnuMetricsMgr != nil {
4428 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00004429 } else {
4430 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004431 }
4432 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004433 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00004434 {
4435 dh.lockUpgradeFsm.RLock()
4436 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00004437 if dh.pOnuUpradeFsm != nil {
4438 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
4439 } else {
4440 return true //FSM not active - so there is no activity on omci
4441 }
mpagenko80622a52021-02-09 16:53:23 +00004442 }
mpagenkof1fc3862021-02-16 10:09:52 +00004443 default:
4444 {
4445 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004446 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00004447 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004448 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004449 }
mpagenkofbf577d2021-10-12 11:44:33 +00004450 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
4451 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
4452 }
4453 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004454}
4455
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004456func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
4457 for _, v := range dh.pOnuTP.PAniConfigFsm {
4458 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004459 return false
4460 }
4461 }
4462 return true
4463}
4464
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304465//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004466func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004467 dh.lockVlanConfig.RLock()
4468 defer dh.lockVlanConfig.RUnlock()
4469 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004470 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004471 return false
4472 }
4473 }
4474 return true //FSM not active - so there is no activity on omci
4475}
4476
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304477//nolint:unparam
mpagenkof1fc3862021-02-16 10:09:52 +00004478func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
4479 dh.lockVlanConfig.RLock()
4480 defer dh.lockVlanConfig.RUnlock()
4481 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004482 if v.PAdaptFsm.PFsm != nil {
4483 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004484 return true //there is at least one VLAN FSM with some active configuration
4485 }
4486 }
4487 }
4488 return false //there is no VLAN FSM with some active configuration
4489}
4490
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004491func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004492 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
4493 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
4494 return false
4495 }
4496 }
4497 // a further check is done to identify, if at least some data traffic related configuration exists
4498 // 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])
4499 return dh.checkUserServiceExists(ctx)
4500}
4501
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004502func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304503 logger.Info(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004504 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004505 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004506 // TODO: fatal error reset ONU, delete deviceHandler!
4507 return
4508 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004509 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
4510 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004511}
4512
4513func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
4514 dh.mutexCollectorFlag.Lock()
4515 dh.collectorIsRunning = flagValue
4516 dh.mutexCollectorFlag.Unlock()
4517}
4518
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004519func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004520 dh.mutexCollectorFlag.RLock()
4521 flagValue := dh.collectorIsRunning
4522 dh.mutexCollectorFlag.RUnlock()
4523 return flagValue
4524}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304525
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304526func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
4527 dh.mutextAlarmManagerFlag.Lock()
4528 dh.alarmManagerIsRunning = flagValue
4529 dh.mutextAlarmManagerFlag.Unlock()
4530}
4531
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004532func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304533 dh.mutextAlarmManagerFlag.RLock()
4534 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004535 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304536 dh.mutextAlarmManagerFlag.RUnlock()
4537 return flagValue
4538}
4539
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004540func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004541 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
bseeniva596a5222026-01-23 19:26:11 +05304542 dh.RLockMutexDeletionInProgressFlag()
4543 if dh.GetDeletionInProgress() {
4544 logger.Warnw(ctx, "Device deletion in progress - avoid starting alarm manager", log.Fields{"device-id": dh.DeviceID})
4545 dh.RUnlockMutexDeletionInProgressFlag()
4546 return
4547 }
4548 // Set alarmManagerIsRunning flag to true while still holding deviceDeletionFlag lock,
4549 // to avoid potential race condition where resetFsm from DeleteDevice might avoid stopping the alarm manager if this flag is not yet set
4550 dh.setAlarmManagerIsRunning(true)
4551
4552 dh.RUnlockMutexDeletionInProgressFlag()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304553
4554 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004555 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304556 if stop := <-dh.stopAlarmManager; stop {
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05304557 logger.Debugw(ctx, "stopping-alarm-manager-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawlad3dac422021-03-13 02:31:31 +05304558 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004559 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
4560 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05304561 }
Himani Chawlad3dac422021-03-13 02:31:31 +05304562 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004563 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
4564 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05304565 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304566 }
4567}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00004568
Girish Gowdrae95687a2021-09-08 16:30:58 -07004569func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
4570 dh.mutexFlowMonitoringRoutineFlag.Lock()
4571 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004572 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004573 dh.isFlowMonitoringRoutineActive[uniID] = flag
4574}
4575
4576func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
4577 dh.mutexFlowMonitoringRoutineFlag.RLock()
4578 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
4579 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004580 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Sridhar Ravindrae9a8bcc2024-12-06 10:40:54 +05304581 if len(dh.isFlowMonitoringRoutineActive) != 0 {
4582 return dh.isFlowMonitoringRoutineActive[uniID]
4583 }
4584 return false
Girish Gowdrae95687a2021-09-08 16:30:58 -07004585}
4586
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004587func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304588 logger.Info(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004589
Maninder7961d722021-06-16 22:10:28 +05304590 connectStatus := voltha.ConnectStatus_UNREACHABLE
4591 operState := voltha.OperStatus_UNKNOWN
4592
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004593 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004594 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004595 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004596 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004597 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004598 case success := <-dh.chReconcilingFinished:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304599 logger.Info(ctx, "reconciling finished signal received",
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004600 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4601 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4602 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4603 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4604 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4605 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4606 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4607 // However, a later refactoring of the functionality remains unaffected.
4608 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004609 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004610 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304611 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004612 log.Fields{"device-id": dh.DeviceID})
akashreddykb03dde02025-12-02 10:53:18 +05304613 } else if !onuDevEntry.SOnuPersistentData.PersRebootInProgress {
mpagenko2c3f6c52021-11-23 11:22:10 +00004614 onuDevEntry.MutexPersOnuConfig.RLock()
mgoudad611f4c2025-10-30 14:49:27 +05304615 switch onuDevEntry.SOnuPersistentData.PersOperState {
4616 case "up":
Maninderb5187552021-03-23 22:23:42 +05304617 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004618 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4619 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304620 operState = voltha.OperStatus_ACTIVE
4621 } else {
4622 operState = voltha.OperStatus_ACTIVATING
4623 }
4624 }
mgoudad611f4c2025-10-30 14:49:27 +05304625 case "down", "unknown", "":
Maninderb5187552021-03-23 22:23:42 +05304626 operState = voltha.OperStatus_DISCOVERED
4627 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004628 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004629 logger.Debugw(ctx, "Core DeviceStateUpdate",
4630 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304631 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304632 logger.Info(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004633 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004634 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004635 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004636 ConnStatus: connectStatus,
4637 OperStatus: operState,
4638 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304639 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004640 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304641 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004642 } else {
Maninderb5187552021-03-23 22:23:42 +05304643 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004644 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304645
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004646 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304647 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004648 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004649 } else {
4650 onuDevEntry.MutexPersOnuConfig.RLock()
4651 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4652 connectStatus = voltha.ConnectStatus_REACHABLE
4653 }
4654 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304655 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004656 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004657 }
mpagenko101ac942021-11-16 15:01:29 +00004658 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004659 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004660 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004661 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304662
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004663 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304664 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004665 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004666 } else {
4667 onuDevEntry.MutexPersOnuConfig.RLock()
4668 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4669 connectStatus = voltha.ConnectStatus_REACHABLE
4670 }
4671 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304672 }
4673
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004674 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304675
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004676 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004677 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004678 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004679 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004680 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004681
4682 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4683 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4684 } else {
4685 onuDevEntry.MutexReconciledTpInstances.Lock()
mgoudad611f4c2025-10-30 14:49:27 +05304686 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]ia.TechProfileDownloadMessage)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004687 onuDevEntry.MutexReconciledTpInstances.Unlock()
4688 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004689 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004690 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004691 dh.mutexReconcilingFlag.Lock()
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304692 if skipOnuConfig || dh.GetSkipOnuConfigEnabled() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004693 dh.reconciling = cSkipOnuConfigReconciling
4694 } else {
4695 dh.reconciling = cOnuConfigReconciling
4696 }
4697 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004698}
4699
mpagenko101ac942021-11-16 15:01:29 +00004700func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304701 logger.Warn(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004702 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004703 dh.sendChReconcileFinished(success)
4704 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4705 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4706 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004707 } else {
mpagenko101ac942021-11-16 15:01:29 +00004708 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004709 }
4710}
4711
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004712func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004713 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004714 defer dh.mutexReconcilingFlag.RUnlock()
4715 return dh.reconciling != cNoReconciling
4716}
4717
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004718func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004719 dh.mutexReconcilingFlag.RLock()
4720 defer dh.mutexReconcilingFlag.RUnlock()
4721 return dh.reconciling == cSkipOnuConfigReconciling
4722}
4723
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004724func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4725 dh.mutexReconcilingFirstPassFlag.Lock()
4726 dh.reconcilingFirstPass = value
4727 dh.mutexReconcilingFirstPassFlag.Unlock()
4728}
4729
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004730func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4731 dh.mutexReconcilingReasonUpdate.Lock()
4732 dh.reconcilingReasonUpdate = value
4733 dh.mutexReconcilingReasonUpdate.Unlock()
4734}
4735
4736func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4737 dh.mutexReconcilingReasonUpdate.RLock()
4738 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4739 return dh.reconcilingReasonUpdate
4740}
4741
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004742func (dh *deviceHandler) getDeviceReason() uint8 {
4743 dh.mutexDeviceReason.RLock()
4744 value := dh.deviceReason
4745 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004746 return value
4747}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004748
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004749func (dh *deviceHandler) GetDeviceReasonString() string {
4750 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004751}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004752
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004753func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004754 dh.mutexReadyForOmciConfig.Lock()
4755 dh.readyForOmciConfig = flagValue
4756 dh.mutexReadyForOmciConfig.Unlock()
4757}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004758func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004759 dh.mutexReadyForOmciConfig.RLock()
4760 flagValue := dh.readyForOmciConfig
4761 dh.mutexReadyForOmciConfig.RUnlock()
4762 return flagValue
4763}
Maninder7961d722021-06-16 22:10:28 +05304764
4765func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004766 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304767 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004768 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304769 }
4770
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004771 logger.Debugw(ctx, "Core DeviceStateUpdate",
4772 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004773 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004774 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004775 ConnStatus: connectStatus,
4776 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4777 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304778 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004779 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304780 }
4781}
khenaidoo7d3c5582021-08-11 18:09:44 -04004782
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05304783func (dh *deviceHandler) deviceRebootStateUpdate(ctx context.Context, techProfInstLoadFailed bool) {
4784 if techProfInstLoadFailed {
4785 if err := dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, true); err != nil {
4786 logger.Errorw(ctx, "unable to update device reason to core",
4787 log.Fields{"device-id": dh.DeviceID, "Err": err})
4788 }
4789 context := make(map[string]string)
4790 context["device-id"] = dh.DeviceID
4791 context["onu-serial-number"] = dh.device.SerialNumber
4792 context["parent-id"] = dh.parentID
4793
4794 // Send event on flow configuration failure so that corrective action can be triggered from NB
4795 deviceEvent := &voltha.DeviceEvent{
4796 ResourceId: dh.DeviceID,
4797 DeviceEventName: cmn.OnuFlowConfigFailed,
4798 Description: cmn.OnuFlowConfigFailedDesc,
4799 Context: context,
4800 }
4801 logger.Debugw(ctx, "send device event", log.Fields{"deviceEvent": deviceEvent, "device-id": dh.DeviceID})
4802 _ = dh.EventProxy.SendDeviceEvent(ctx, deviceEvent, voltha.EventCategory_EQUIPMENT, voltha.EventSubCategory_ONU, time.Now().Unix())
4803 }
4804}
4805
khenaidoo7d3c5582021-08-11 18:09:44 -04004806/*
4807Helper functions to communicate with Core
4808*/
4809
4810func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4811 cClient, err := dh.coreClient.GetCoreServiceClient()
4812 if err != nil || cClient == nil {
4813 return nil, err
4814 }
4815 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4816 defer cancel()
4817 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
mgoudad611f4c2025-10-30 14:49:27 +05304818 return cClient.GetDevice(subCtx, &common.ID{Id: deviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04004819}
4820
khenaidoo42dcdfd2021-10-19 17:34:12 -04004821func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004822 cClient, err := dh.coreClient.GetCoreServiceClient()
4823 if err != nil || cClient == nil {
4824 return err
4825 }
4826 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4827 defer cancel()
4828 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004829 logger.Debugw(subCtx, "device-updated-in-core",
4830 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004831 return err
4832}
4833
4834func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4835 cClient, err := dh.coreClient.GetCoreServiceClient()
4836 if err != nil || cClient == nil {
4837 return err
4838 }
4839 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4840 defer cancel()
4841 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004842 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4843 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004844 return err
4845}
4846
4847func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4848 cClient, err := dh.coreClient.GetCoreServiceClient()
4849 if err != nil || cClient == nil {
4850 return err
4851 }
4852 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4853 defer cancel()
4854 _, err = cClient.DeviceUpdate(subCtx, device)
4855 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4856 return err
4857}
4858
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004859func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004860 cClient, err := dh.coreClient.GetCoreServiceClient()
4861 if err != nil || cClient == nil {
4862 return err
4863 }
4864 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4865 defer cancel()
4866 _, err = cClient.PortCreated(subCtx, port)
4867 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4868 return err
4869}
4870
khenaidoo42dcdfd2021-10-19 17:34:12 -04004871func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004872 cClient, err := dh.coreClient.GetCoreServiceClient()
4873 if err != nil || cClient == nil {
4874 return err
4875 }
4876 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4877 defer cancel()
4878 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004879 logger.Debugw(subCtx, "port-state-updated-in-core", log.Fields{"device-id": dh.device.Id, "port-state": portState, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004880 return err
4881}
4882
khenaidoo42dcdfd2021-10-19 17:34:12 -04004883func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004884 cClient, err := dh.coreClient.GetCoreServiceClient()
4885 if err != nil || cClient == nil {
4886 return err
4887 }
4888 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4889 defer cancel()
4890 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004891 logger.Debugw(subCtx, "device-reason-updated-in-core", log.Fields{"device-id": dh.device.Id, "reason": reason, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004892 return err
4893}
4894
4895/*
4896Helper functions to communicate with parent adapter
4897*/
4898
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004899func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4900 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4901
4902 var request = ia.TechProfileInstanceRequestMessage{
4903 DeviceId: dh.DeviceID,
4904 TpInstancePath: aTpPath,
4905 ParentDeviceId: dh.parentID,
4906 ParentPonPort: dh.device.ParentPortNo,
4907 OnuId: dh.device.ProxyAddress.OnuId,
4908 UniId: uint32(aUniID),
4909 }
4910
4911 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004912 if err != nil || pgClient == nil {
4913 return nil, err
4914 }
4915 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4916 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004917 logger.Debugw(subCtx, "get-tech-profile-instance",
4918 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004919 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004920}
4921
Girish Gowdrae95687a2021-09-08 16:30:58 -07004922// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4923// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4924func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4925 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4926 dh.setFlowMonitoringIsRunning(uniID, true)
4927 for {
4928 select {
4929 // block on the channel to receive an incoming flow
4930 // process the flow completely before proceeding to handle the next flow
4931 case flowCb := <-dh.flowCbChan[uniID]:
4932 startTime := time.Now()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304933 logger.Info(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004934 respChan := make(chan error)
4935 if flowCb.addFlow {
4936 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4937 } else {
4938 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4939 }
4940 // Block on response and tunnel it back to the caller
balaji.nagarajan62ac62b2025-09-08 10:49:58 +05304941 select {
4942
4943 case msg := <-respChan:
4944 *flowCb.respChan <- msg
4945 // response sent successfully
4946 logger.Info(flowCb.ctx, "serial-flow-processor--end",
4947 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4948 case <-flowCb.ctx.Done():
4949 logger.Info(flowCb.ctx, "flow handler context cancelled or timed out", log.Fields{"device-id": dh.DeviceID})
4950 // Optionally, you can handle cleanup or logging here
4951 if dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID] != nil && dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID].PAdaptFsm != nil {
4952 pVlanFilterStatemachine := dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID].PAdaptFsm.PFsm
4953 if pVlanFilterStatemachine != nil {
4954
4955 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
4956 logger.Warnw(flowCb.ctx, "UniVlanConfigFsm: can't reset",
4957 log.Fields{"device-id": dh.DeviceID, "err": err})
4958
4959 }
4960
4961 }
4962 }
4963
4964 ctx2 := context.Background()
4965 metadata := flow.GetMetadataFromWriteMetadataAction(ctx2, flowCb.flowItem)
4966 if metadata == 0 {
4967 logger.Warnw(flowCb.ctx, "AniConfigFsm: can't reset,failed to fetch metadata flow: %v",
4968 log.Fields{"device-id": dh.DeviceID, "flows": flowCb.flowItem})
4969 continue
4970 }
4971 TpID := flow.GetTechProfileIDFromWriteMetaData(ctx2, metadata)
4972
4973 if TpID == uint16(0) {
4974 logger.Warnw(flowCb.ctx, "AniConfigFsm: can't reset,failed to fetch techprofileid flow: %v",
4975 log.Fields{"device-id": dh.DeviceID, "flows": flowCb.flowItem})
4976 continue
4977 }
4978 if dh.pOnuTP != nil {
4979 // should always be the case here
4980 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
4981 if dh.pOnuTP.PAniConfigFsm != nil {
4982 uniTP := avcfg.UniTP{
4983 UniID: flowCb.uniPort.UniID,
4984 TpID: uint8(TpID),
4985 }
4986 if dh.pOnuTP.PAniConfigFsm[uniTP] != nil {
4987 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(context.Background())
4988 }
4989 }
4990 }
4991
4992 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07004993 case <-dh.stopFlowMonitoringRoutine[uniID]:
4994 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4995 dh.setFlowMonitoringIsRunning(uniID, false)
4996 return
4997 }
4998 }
4999}
5000
kesavand011d5162021-11-25 19:21:06 +05305001func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
5002 request.ParentDeviceId = dh.GetProxyAddressID()
5003 request.ChildDeviceId = dh.DeviceID
5004 request.ProxyAddress = dh.GetProxyAddress()
5005 request.ConnectStatus = common.ConnectStatus_REACHABLE
5006
5007 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
5008 if err != nil || pgClient == nil {
5009 return err
5010 }
5011 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
5012 defer cancel()
5013 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
5014 _, err = pgClient.ProxyOmciRequests(subCtx, request)
5015 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00005016 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
5017 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05305018 }
5019 return err
5020}
5021
khenaidoo42dcdfd2021-10-19 17:34:12 -04005022func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04005023 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
5024 if err != nil || pgClient == nil {
5025 return err
5026 }
5027 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
5028 defer cancel()
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005029 dh.setOltAvailable(true)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00005030 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04005031 _, err = pgClient.ProxyOmciRequest(subCtx, request)
5032 if err != nil {
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005033 if status.Code(err) == codes.Unavailable {
5034 dh.setOltAvailable(false)
5035 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00005036 logger.Errorw(ctx, "omci-failure",
5037 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005038 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress, "oltAvailable": dh.IsOltAvailable})
khenaidoo7d3c5582021-08-11 18:09:44 -04005039 }
5040 return err
5041}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005042
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005043func (dh *deviceHandler) CheckAvailableOnuCapabilities(ctx context.Context, pDevEntry *mib.OnuDeviceEntry, tpInst tech_profile.TechProfileInstance) error {
5044 // Check if there are additional TCONT instances necessary/available
5045 pDevEntry.MutexPersOnuConfig.Lock()
5046 if _, ok := pDevEntry.SOnuPersistentData.PersTcontMap[uint16(tpInst.UsScheduler.AllocId)]; !ok {
5047 numberOfTcontMapEntries := len(pDevEntry.SOnuPersistentData.PersTcontMap)
5048 pDevEntry.MutexPersOnuConfig.Unlock()
5049 numberOfTcontDbInsts := pDevEntry.GetOnuDB().GetNumberOfInst(me.TContClassID)
5050 logger.Debugw(ctx, "checking available TCONT instances",
5051 log.Fields{"device-id": dh.DeviceID, "numberOfTcontMapEntries": numberOfTcontMapEntries, "numberOfTcontDbInsts": numberOfTcontDbInsts})
5052 if numberOfTcontMapEntries >= numberOfTcontDbInsts {
5053 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of TCONT instances: send ONU device event!",
5054 log.Fields{"device-id": dh.device.Id})
5055 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingTcont, cmn.OnuConfigFailureMissingTcontDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305056 return fmt.Errorf("configuration exceeds ONU capabilities - running out of TCONT instances: device-id: %s", dh.DeviceID)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005057 }
5058 } else {
5059 pDevEntry.MutexPersOnuConfig.Unlock()
5060 }
5061 // Check if there are enough PrioQueue instances available
5062 if dh.pOnuTP != nil {
5063 var numberOfUsPrioQueueDbInsts int
5064
5065 queueInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(ctx, me.PriorityQueueClassID)
5066 for _, mgmtEntityID := range queueInstKeys {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305067 if mgmtEntityID >= 0x8000 {
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005068 numberOfUsPrioQueueDbInsts++
5069 }
5070 }
5071 // Check if there is an upstream PriorityQueue instance available for each Gem port
5072 numberOfConfiguredGemPorts := dh.pOnuTP.GetNumberOfConfiguredUsGemPorts(ctx)
5073 logger.Debugw(ctx, "checking available upstream PriorityQueue instances",
5074 log.Fields{"device-id": dh.DeviceID,
5075 "numberOfConfiguredGemPorts": numberOfConfiguredGemPorts,
5076 "tpInst.NumGemPorts": tpInst.NumGemPorts,
5077 "numberOfUsPrioQueueDbInsts": numberOfUsPrioQueueDbInsts})
5078
5079 if numberOfConfiguredGemPorts+int(tpInst.NumGemPorts) > numberOfUsPrioQueueDbInsts {
5080 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: send ONU device event!",
5081 log.Fields{"device-id": dh.device.Id})
5082 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingUsPriorityQueue, cmn.OnuConfigFailureMissingUsPriorityQueueDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305083 return fmt.Errorf("configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: device-id: %s", dh.DeviceID)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005084 }
5085 // Downstream PrioQueue instances are evaluated in accordance with ONU MIB upload data in function UniPonAniConfigFsm::prepareAndEnterConfigState().
5086 // In case of missing downstream PrioQueues the attribute "Priority queue pointer for downstream" of ME "GEM port network CTP" will be set to "0",
5087 // which then alternatively activates the queuing mechanisms of the ONU (refer to Rec. ITU-T G.988 chapter 9.2.3).
5088 } else {
5089 logger.Warnw(ctx, "onuTechProf instance not set up - check for PriorityQueue instances skipped!",
5090 log.Fields{"device-id": dh.DeviceID})
5091 }
5092 return nil
5093}
5094
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005095// GetDeviceID - TODO: add comment
5096func (dh *deviceHandler) GetDeviceID() string {
5097 return dh.DeviceID
5098}
5099
5100// GetProxyAddressID - TODO: add comment
5101func (dh *deviceHandler) GetProxyAddressID() string {
5102 return dh.device.ProxyAddress.GetDeviceId()
5103}
5104
5105// GetProxyAddressType - TODO: add comment
5106func (dh *deviceHandler) GetProxyAddressType() string {
5107 return dh.device.ProxyAddress.GetDeviceType()
5108}
5109
5110// GetProxyAddress - TODO: add comment
5111func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
5112 return dh.device.ProxyAddress
5113}
5114
5115// GetEventProxy - TODO: add comment
5116func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
5117 return dh.EventProxy
5118}
5119
5120// GetOmciTimeout - TODO: add comment
5121func (dh *deviceHandler) GetOmciTimeout() int {
5122 return dh.pOpenOnuAc.omciTimeout
5123}
5124
5125// GetAlarmAuditInterval - TODO: add comment
5126func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
5127 return dh.pOpenOnuAc.alarmAuditInterval
5128}
5129
5130// GetDlToOnuTimeout4M - TODO: add comment
5131func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
5132 return dh.pOpenOnuAc.dlToOnuTimeout4M
5133}
5134
5135// GetUniEntityMap - TODO: add comment
5136func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
5137 return &dh.uniEntityMap
5138}
5139
5140// GetPonPortNumber - TODO: add comment
5141func (dh *deviceHandler) GetPonPortNumber() *uint32 {
5142 return &dh.ponPortNumber
5143}
5144
5145// GetUniVlanConfigFsm - TODO: add comment
5146func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00005147 dh.lockVlanConfig.RLock()
5148 value := dh.UniVlanConfigFsmMap[uniID]
5149 dh.lockVlanConfig.RUnlock()
5150 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005151}
5152
5153// GetOnuAlarmManager - TODO: add comment
5154func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
5155 return dh.pAlarmMgr
5156}
5157
5158// GetOnuMetricsManager - TODO: add comment
5159func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
5160 return dh.pOnuMetricsMgr
5161}
5162
5163// GetOnuTP - TODO: add comment
5164func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
5165 return dh.pOnuTP
5166}
5167
5168// GetBackendPathPrefix - TODO: add comment
5169func (dh *deviceHandler) GetBackendPathPrefix() string {
5170 return dh.pOpenOnuAc.cm.Backend.PathPrefix
5171}
5172
5173// GetOnuIndication - TODO: add comment
mgoudad611f4c2025-10-30 14:49:27 +05305174func (dh *deviceHandler) GetOnuIndication() *oop.OnuIndication {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005175 return dh.pOnuIndication
5176}
5177
5178// RLockMutexDeletionInProgressFlag - TODO: add comment
5179func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
5180 dh.mutexDeletionInProgressFlag.RLock()
5181}
5182
5183// RUnlockMutexDeletionInProgressFlag - TODO: add comment
5184func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
5185 dh.mutexDeletionInProgressFlag.RUnlock()
5186}
5187
5188// GetDeletionInProgress - TODO: add comment
5189func (dh *deviceHandler) GetDeletionInProgress() bool {
5190 return dh.deletionInProgress
5191}
5192
5193// GetPmConfigs - TODO: add comment
5194func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
5195 return dh.pmConfigs
5196}
5197
5198// GetDeviceType - TODO: add comment
5199func (dh *deviceHandler) GetDeviceType() string {
5200 return dh.DeviceType
5201}
5202
5203// GetLogicalDeviceID - TODO: add comment
5204func (dh *deviceHandler) GetLogicalDeviceID() string {
5205 return dh.logicalDeviceID
5206}
5207
5208// GetDevice - TODO: add comment
5209func (dh *deviceHandler) GetDevice() *voltha.Device {
5210 return dh.device
5211}
5212
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005213func (dh *deviceHandler) setOltAvailable(value bool) {
5214 dh.mutexOltAvailable.Lock()
5215 dh.oltAvailable = value
5216 dh.mutexOltAvailable.Unlock()
5217}
5218
5219// IsOltAvailable - TODO: add comment
5220func (dh *deviceHandler) IsOltAvailable() bool {
5221 dh.mutexOltAvailable.RLock()
5222 defer dh.mutexOltAvailable.RUnlock()
5223 return dh.oltAvailable
5224}
5225
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005226// GetMetricsEnabled - TODO: add comment
5227func (dh *deviceHandler) GetMetricsEnabled() bool {
5228 return dh.pOpenOnuAc.MetricsEnabled
5229}
5230
Holger Hildebrandtc572e622022-06-22 09:19:17 +00005231// GetExtendedOmciSupportEnabled - TODO: add comment
5232func (dh *deviceHandler) GetExtendedOmciSupportEnabled() bool {
5233 return dh.pOpenOnuAc.ExtendedOmciSupportEnabled
5234}
5235
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05305236// GetExtendedOmciSupportEnabled - TODO: add comment
5237func (dh *deviceHandler) GetSkipOnuConfigEnabled() bool {
5238 return dh.pOpenOnuAc.skipOnuConfig
5239}
5240
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05305241func (dh *deviceHandler) GetDeviceTechProfOnReboot() bool {
5242 return dh.pOpenOnuAc.CheckDeviceTechProfOnReboot
5243}
5244
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005245// InitPmConfigs - TODO: add comment
5246func (dh *deviceHandler) InitPmConfigs() {
5247 dh.pmConfigs = &voltha.PmConfigs{}
5248}
5249
5250// GetUniPortMask - TODO: add comment
5251func (dh *deviceHandler) GetUniPortMask() int {
5252 return dh.pOpenOnuAc.config.UniPortMask
5253}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00005254
5255func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
5256 tpPathFound := false
5257 for _, tpPath := range aTpPathMap {
5258 if tpPath != "" {
5259 tpPathFound = true
5260 }
5261 }
5262 return tpPathFound
5263}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005264
praneeth nalmas5a0a5502022-12-23 15:57:00 +05305265func (dh *deviceHandler) getOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
5266 resp := dh.GetOnuAlarmManager().GetOnuActiveAlarms(ctx)
5267 logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
5268 return resp
5269}
5270
Akash Reddy Kankanalac28f0e22025-06-16 11:00:55 +05305271// getONUGEMStatsInfo - Get the GEM PM history data of the request ONT device
5272func (dh *deviceHandler) getONUGEMStatsInfo(ctx context.Context) *extension.SingleGetValueResponse {
5273 resp := dh.pOnuMetricsMgr.GetONUGEMCounters(ctx)
pnalmas6d6b7d72025-10-23 16:34:22 +05305274 logger.Debugw(ctx, "Received response from ONU Metrics Manager for GEM Stats", log.Fields{"device-id": dh.DeviceID})
5275 return resp
5276}
5277
5278// getOnuFECStats - Get the GEM PM history data of the request ONT device
5279func (dh *deviceHandler) getOnuFECStats(ctx context.Context) *extension.SingleGetValueResponse {
5280 resp := dh.pOnuMetricsMgr.GetONUFECCounters(ctx)
5281 logger.Debugw(ctx, "Received response from ONU Metrics Manager for FEC Stats", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanalac28f0e22025-06-16 11:00:55 +05305282 return resp
5283}
5284
Praneeth Kumar Nalmasaacc6122024-04-09 22:55:49 +05305285func (dh *deviceHandler) GetDeviceDeleteCommChan(ctx context.Context) chan bool {
5286 return dh.deviceDeleteCommChan
5287}
5288
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005289// PrepareForGarbageCollection - remove references to prepare for garbage collection
5290func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
5291 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
5292
5293 // Note: This function must be called as a goroutine to prevent blocking of further processing!
5294 // first let the objects rest for some time to give all asynchronously started
5295 // cleanup routines a chance to come to an end
Holger Hildebrandt12609a12022-03-25 13:23:25 +00005296 time.Sleep(2 * time.Second)
5297
Holger Hildebrandt12609a12022-03-25 13:23:25 +00005298 time.Sleep(3 * time.Second)
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005299
5300 if dh.pOnuTP != nil {
5301 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
5302 }
5303 if dh.pOnuMetricsMgr != nil {
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00005304 logger.Debugw(ctx, "preparation of garbage collection is done under control of pm fsm - wait for completion",
5305 log.Fields{"device-id": aDeviceID})
Girish Gowdraabcceb12022-04-13 23:35:22 -07005306 select {
5307 case <-dh.pOnuMetricsMgr.GarbageCollectionComplete:
5308 logger.Debugw(ctx, "pm fsm shut down and garbage collection complete", log.Fields{"deviceID": aDeviceID})
5309 case <-time.After(pmmgr.MaxTimeForPmFsmShutDown * time.Second):
5310 logger.Errorw(ctx, "fsm did not shut down in time", log.Fields{"deviceID": aDeviceID})
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00005311 default:
Girish Gowdraabcceb12022-04-13 23:35:22 -07005312 }
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005313 }
5314 if dh.pAlarmMgr != nil {
5315 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
5316 }
5317 if dh.pSelfTestHdlr != nil {
5318 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
5319 }
5320 if dh.pLockStateFsm != nil {
5321 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5322 }
5323 if dh.pUnlockStateFsm != nil {
5324 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5325 }
5326 if dh.pOnuUpradeFsm != nil {
5327 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5328 }
5329 if dh.pOnuOmciDevice != nil {
5330 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
5331 }
5332 for k, v := range dh.UniVlanConfigFsmMap {
5333 v.PrepareForGarbageCollection(ctx, aDeviceID)
5334 delete(dh.UniVlanConfigFsmMap, k)
5335 }
nikesh.krishnan1249be92023-11-27 04:20:12 +05305336 dh.pOnuIndication = nil
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005337 dh.pOnuOmciDevice = nil
bseeniva0cbc62a2026-01-23 19:08:36 +05305338 dh.lockDevice.Lock()
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005339 dh.pOnuTP = nil
bseeniva0cbc62a2026-01-23 19:08:36 +05305340 dh.lockDevice.Unlock()
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005341 dh.pOnuMetricsMgr = nil
5342 dh.pAlarmMgr = nil
5343 dh.pSelfTestHdlr = nil
5344 dh.pLockStateFsm = nil
5345 dh.pUnlockStateFsm = nil
5346 dh.pOnuUpradeFsm = nil
5347}