blob: e8da229549c2e23e3679633aae003c146c4d393b [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) {
bseenivabc19dec2026-02-04 11:56:23 +0530637 logger.Warnw(ctx, "FlowUpdateIncremental ignored as device is being configured post reboot", log.Fields{"device-id": dh.DeviceID})
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +0530638 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 {
bseenivabc19dec2026-02-04 11:56:23 +05301464 logger.Infow(ctx, "Check for tech profile config", log.Fields{"device-id": dh.DeviceID})
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301465 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 }
bseenivabc19dec2026-02-04 11:56:23 +05301635 if dh.GetDeviceTechProfOnReboot() {
1636 dh.UpdateAndStoreRebootState(ctx, true)
1637 }
akashreddyke30dfa92025-11-26 10:51:57 +05301638 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
1639 logger.Errorw(ctx, "errror-updating-device-reason-to-core", log.Fields{"device-id": dh.DeviceID, "error": err})
1640 return
1641 }
1642 dh.SetReadyForOmciConfig(false)
1643 }()
1644 return nil
mpagenko8b07c1b2020-11-26 10:36:31 +00001645 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1646 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1647 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1648 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001649}
1650
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301651// doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
1652//
1653// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001654func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001655 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001656 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001657 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001658
1659 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001660 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001661 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001662 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1663 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001664 }
1665
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001666 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001667 var inactiveImageID uint16
1668 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1669 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001670 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1671 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001672 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001673 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001674 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001675 if err == nil {
1676 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1677 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001678 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001679 }
1680 } else {
1681 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001682 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001683 }
mpagenko15ff4a52021-03-02 10:09:20 +00001684 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001685 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001686 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001687 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1688 dh.upgradeCanceled = true
1689 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1690 }
mpagenko38662d02021-08-11 09:45:19 +00001691 //no effort spent anymore for the old API to automatically cancel and restart the download
1692 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001693 }
mpagenko15ff4a52021-03-02 10:09:20 +00001694 } else {
1695 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001696 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001697 }
1698 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001699 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1700 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001701 }
1702 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001703}
1704
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301705// onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
mpagenkoc26d4c02021-05-06 14:27:57 +00001706// after the OnuImage has been downloaded to the adapter, called in background
1707func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001708 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001709
1710 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001711 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001712 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001713 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001714 return
1715 }
1716
1717 var inactiveImageID uint16
1718 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1719 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001720 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001721
mpagenko59862f02021-10-11 08:53:18 +00001722 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001723 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001724 // but must be still locked at calling createOnuUpgradeFsm
1725 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1726 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1727 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001728 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1729 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001730 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001731 //flush the remove upgradeFsmChan channel
1732 select {
1733 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001734 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001735 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001736 }
mpagenko59862f02021-10-11 08:53:18 +00001737 dh.lockUpgradeFsm.Unlock()
1738 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1739 dh.upgradeCanceled = true
1740 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1741 }
mpagenko38662d02021-08-11 09:45:19 +00001742 select {
1743 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001744 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001745 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1746 return
1747 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001748 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001749 }
mpagenko59862f02021-10-11 08:53:18 +00001750 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001751 }
mpagenko38662d02021-08-11 09:45:19 +00001752
1753 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001754 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001755 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001756 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001757 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001758 if err == nil {
1759 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1760 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1761 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001762 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001763 return
1764 }
mpagenko38662d02021-08-11 09:45:19 +00001765 } else {
1766 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001767 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001768 }
1769 return
1770 }
1771 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001772 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001773}
1774
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301775// onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001776func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1777 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001778 var err error
1779 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1780 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1781 // 2.) activation of the inactive image
1782
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001783 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001784 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001785 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1786 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001787 }
1788 dh.lockUpgradeFsm.RLock()
1789 if dh.pOnuUpradeFsm != nil {
1790 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001791 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001792 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001793 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1794 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001795 }
mpagenko59862f02021-10-11 08:53:18 +00001796 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1797 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1798 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1799 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001800 // use the OnuVendor identification from this device for the internal unique name
1801 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001802 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001803 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001804 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001805 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001806 "device-id": dh.DeviceID, "error": err})
1807 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001808 }
mpagenko183647c2021-06-08 15:25:04 +00001809 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001810 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001811 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001812 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001813 } //else
1814 dh.lockUpgradeFsm.RUnlock()
1815
1816 // 2.) check if requested image-version equals the inactive one and start its activation
1817 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1818 var inactiveImageID uint16
1819 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1820 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001821 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1822 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001823 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001824 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001825 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001826 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001827 if err == nil {
1828 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1829 inactiveImageID, aCommitRequest); err != nil {
1830 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001831 "device-id": dh.DeviceID, "error": err})
1832 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001833 }
1834 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001835 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001836 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001837 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001838 } //else
1839 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001840 "device-id": dh.DeviceID, "error": err})
1841 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001842}
1843
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301844// onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001845func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1846 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001847 var err error
1848 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1849 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1850 // 2.) commitment of the active image
1851
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001852 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001853 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001854 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1855 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001856 }
1857 dh.lockUpgradeFsm.RLock()
1858 if dh.pOnuUpradeFsm != nil {
1859 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001860 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001861 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001862 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1863 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001864 }
mpagenko59862f02021-10-11 08:53:18 +00001865 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1866 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1867 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1868 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001869 // use the OnuVendor identification from this device for the internal unique name
1870 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001871 // 1.) check a started upgrade process and relay the commitment request to it
1872 // the running upgrade may be based either on the imageIdentifier (started from download)
1873 // or on the imageVersion (started from pure activation)
1874 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1875 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001876 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001877 "device-id": dh.DeviceID, "error": err})
1878 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001879 }
mpagenko183647c2021-06-08 15:25:04 +00001880 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001881 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001882 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001883 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001884 } //else
1885 dh.lockUpgradeFsm.RUnlock()
1886
mpagenko183647c2021-06-08 15:25:04 +00001887 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001888 var activeImageID uint16
1889 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1890 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001891 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1892 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001893 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001894 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001895 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001896 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001897 if err == nil {
1898 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1899 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001900 "device-id": dh.DeviceID, "error": err})
1901 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001902 }
1903 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001904 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001905 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001906 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001907 } //else
1908 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001909 "device-id": dh.DeviceID, "error": err})
1910 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001911}
1912
mpagenkoaa3afe92021-05-21 16:20:58 +00001913func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001914 aVersion string) *voltha.ImageState {
1915 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001916 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001917 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001918 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001919 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1920 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1921 if aVersion == dh.pLastUpgradeImageState.Version {
1922 pImageState = dh.pLastUpgradeImageState
1923 } else { //state request for an image version different from last processed image version
1924 pImageState = &voltha.ImageState{
1925 Version: aVersion,
1926 //we cannot state something concerning this version
1927 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1928 Reason: voltha.ImageState_NO_ERROR,
1929 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1930 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001931 }
1932 }
mpagenko38662d02021-08-11 09:45:19 +00001933 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001934}
1935
1936func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1937 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001938 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001939 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001940 dh.lockUpgradeFsm.RLock()
1941 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001942 dh.lockUpgradeFsm.RUnlock()
1943 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001944 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001945 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1946 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1947 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1948 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1949 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1950 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001951 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1952 dh.upgradeCanceled = true
1953 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1954 }
mpagenko45586762021-10-01 08:30:22 +00001955 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001956 } else {
mpagenko45586762021-10-01 08:30:22 +00001957 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001958 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1959 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1960 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1961 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1962 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1963 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001964 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1965 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001966 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1967 //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 +00001968 }
1969}
1970
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001971func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1972
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001973 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001974
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001975 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001976 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001977 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1978 pDevEntry.MutexOnuImageStatus.Lock()
1979 pDevEntry.POnuImageStatus = onuImageStatus
1980 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001981
1982 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001983 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001984 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1985 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001986 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1987 pDevEntry.MutexOnuImageStatus.Lock()
1988 pDevEntry.POnuImageStatus = nil
1989 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001990 return images, err
1991}
1992
Himani Chawla6d2ae152020-09-02 13:11:20 +05301993// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001994// #####################################################################################
1995
1996// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301997// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001998
dbainbri4d3a0dc2020-12-02 00:33:42 +00001999func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002000 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
2001 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002002}
2003
2004// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00002005func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002006
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002007 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002008 var err error
2009
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002010 // populate what we know. rest comes later after mib sync
2011 dh.device.Root = false
2012 dh.device.Vendor = "OpenONU"
2013 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002014 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00002015 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002016
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002017 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002018
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002019 if !dh.IsReconciling() {
2020 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302021 if err = dh.updateDeviceInCore(ctx, dh.device); err != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -04002022 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2023 }
Himani Chawlac07fda02020-12-09 16:21:21 +05302024 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002025 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302026 logger.Infow(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002027 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002028 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002029
Himani Chawla4d908332020-08-31 12:30:20 +05302030 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002031 dh.ponPortNumber = dh.device.ParentPortNo
2032
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002033 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
2034 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
2035 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002036 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002037 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05302038 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002039
2040 /*
2041 self._pon = PonPort.create(self, self._pon_port_number)
2042 self._pon.add_peer(self.parent_id, self._pon_port_number)
2043 self.logger.debug('adding-pon-port-to-agent',
2044 type=self._pon.get_port().type,
2045 admin_state=self._pon.get_port().admin_state,
2046 oper_status=self._pon.get_port().oper_status,
2047 )
2048 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002049 if !dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302050 logger.Infow(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002051 var ponPortNo uint32 = 1
2052 if dh.ponPortNumber != 0 {
2053 ponPortNo = dh.ponPortNumber
2054 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002055
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002056 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002057 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002058 PortNo: ponPortNo,
2059 Label: fmt.Sprintf("pon-%d", ponPortNo),
2060 Type: voltha.Port_PON_ONU,
2061 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05302062 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002063 PortNo: ponPortNo}}, // Peer port is parent's port number
2064 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002065 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002066 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002067 e.Cancel(err)
2068 return
2069 }
2070 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302071 logger.Infow(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002072 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002073 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002074}
2075
2076// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00002077func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002078
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002079 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002080 var err error
2081 /*
2082 dh.Client = oop.NewOpenoltClient(dh.clientCon)
2083 dh.pTransitionMap.Handle(ctx, GrpcConnected)
2084 return nil
2085 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002086 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002087 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002088 e.Cancel(err)
2089 return
2090 }
2091
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002092 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002093 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002094 // reconcilement will be continued after mib download is done
2095 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002096
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002097 /*
2098 ############################################################################
2099 # Setup Alarm handler
2100 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
2101 device.serial_number)
2102 ############################################################################
2103 # Setup PM configuration for this device
2104 # Pass in ONU specific options
2105 kwargs = {
2106 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
2107 'heartbeat': self.heartbeat,
2108 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
2109 }
2110 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
2111 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
2112 self.logical_device_id, device.serial_number,
2113 grouped=True, freq_override=False, **kwargs)
2114 pm_config = self._pm_metrics.make_proto()
2115 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
2116 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
2117 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
2118
2119 # Note, ONU ID and UNI intf set in add_uni_port method
2120 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
2121 ani_ports=[self._pon])
2122
2123 # Code to Run OMCI Test Action
2124 kwargs_omci_test_action = {
2125 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2126 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2127 }
2128 serial_number = device.serial_number
2129 self._test_request = OmciTestRequest(self.core_proxy,
2130 self.omci_agent, self.device_id,
2131 AniG, serial_number,
2132 self.logical_device_id,
2133 exclusive=False,
2134 **kwargs_omci_test_action)
2135
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002136 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002137 else:
2138 self.logger.info('onu-already-activated')
2139 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08002140
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002141 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002142}
2143
2144// doStateConnected get the device info and update to voltha core
2145// for comparison of the original method (not that easy to uncomment): compare here:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302146//
2147// voltha-openolt-adapter/adaptercore/device_handler.go
2148// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00002149func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002150
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002151 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302152 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002153 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002154 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002155}
2156
2157// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00002158func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002159
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002160 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302161 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002162 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002163 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002164
2165 /*
2166 // Synchronous call to update device state - this method is run in its own go routine
2167 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
2168 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002169 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 +00002170 return err
2171 }
2172 return nil
2173 */
2174}
2175
2176// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00002177func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002178
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002179 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002180 var err error
2181
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002182 device := dh.device
2183 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002184 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002185 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002186 e.Cancel(err)
2187 return
2188 }
2189
2190 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002191 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002192 /*
2193 // Update the all ports state on that device to disable
2194 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002195 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002196 return er
2197 }
2198
2199 //Update the device oper state and connection status
2200 cloned.OperStatus = voltha.OperStatus_UNKNOWN
2201 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
2202 dh.device = cloned
2203
2204 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002205 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002206 return er
2207 }
2208
2209 //get the child device for the parent device
2210 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
2211 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002212 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002213 return err
2214 }
2215 for _, onuDevice := range onuDevices.Items {
2216
2217 // Update onu state as down in onu adapter
2218 onuInd := oop.OnuIndication{}
2219 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04002220 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002221 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
2222 if er != nil {
2223 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00002224 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002225 //Do not return here and continue to process other ONUs
2226 }
2227 }
2228 // * Discovered ONUs entries need to be cleared , since after OLT
2229 // is up, it starts sending discovery indications again* /
2230 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00002231 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002232 return nil
2233 */
Himani Chawla4d908332020-08-31 12:30:20 +05302234 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002235 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002236 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002237}
2238
Himani Chawla6d2ae152020-09-02 13:11:20 +05302239// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002240// #################################################################################
2241
2242// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05302243// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002244
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302245// GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002246func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00002247 dh.lockDevice.RLock()
2248 pOnuDeviceEntry := dh.pOnuOmciDevice
2249 if aWait && pOnuDeviceEntry == nil {
2250 //keep the read sema short to allow for subsequent write
2251 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002252 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002253 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
2254 // so it might be needed to wait here for that event with some timeout
2255 select {
2256 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002257 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002258 return nil
2259 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002260 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002261 // if written now, we can return the written value without sema
2262 return dh.pOnuOmciDevice
2263 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002264 }
mpagenko3af1f032020-06-10 08:53:41 +00002265 dh.lockDevice.RUnlock()
2266 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002267}
2268
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302269// setDeviceHandlerEntries sets the ONU device entry within the handler
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002270func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
2271 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002272 dh.lockDevice.Lock()
2273 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00002274 dh.pOnuOmciDevice = apDeviceEntry
2275 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08002276 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05302277 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002278 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002279}
2280
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302281// addOnuDeviceEntry creates a new ONU device or returns the existing
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302282//
2283//nolint:unparam
Himani Chawla6d2ae152020-09-02 13:11:20 +05302284func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002285 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002286
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002287 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002288 if deviceEntry == nil {
2289 /* costum_me_map in python code seems always to be None,
2290 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
2291 /* also no 'clock' argument - usage open ...*/
2292 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002293 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
2294 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
2295 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
2296 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
2297 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002298 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002299 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00002300 // fire deviceEntry ready event to spread to possibly waiting processing
2301 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002302 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002303 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002304 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002305 }
2306 // might be updated with some error handling !!!
2307 return nil
2308}
2309
dbainbri4d3a0dc2020-12-02 00:33:42 +00002310func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002311 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002312 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
2313
2314 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002315
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002316 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002317 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002318 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2319 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002320 }
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302321
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002322 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002323 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002324 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002325
khenaidoo42dcdfd2021-10-19 17:34:12 -04002326 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002327 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002328 OperStatus: voltha.OperStatus_ACTIVATING,
2329 ConnStatus: voltha.ConnectStatus_REACHABLE,
2330 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002331 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002332 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302333 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
2334 }
2335 // On onu reboot, we have to perform mib-reset and persist the reboot state for reconciling scenario
2336 if dh.GetDeviceTechProfOnReboot() {
2337 pDevEntry.MutexPersOnuConfig.Lock()
2338 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2339 pDevEntry.SOnuPersistentData.PersRebootInProgress = true
akashreddykb03dde02025-12-02 10:53:18 +05302340 pDevEntry.SOnuPersistentData.PersUniUnlockDone = false
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302341 pDevEntry.MutexPersOnuConfig.Unlock()
2342 }
2343 // Moving the previous call to write to KV store here, to store the ONU pers data after the update.
2344 if err := dh.StorePersistentData(ctx); err != nil {
2345 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2346 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002347 }
2348 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302349 logger.Info(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002350 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002351
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002352 pDevEntry.MutexPersOnuConfig.RLock()
2353 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
2354 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002355 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 +00002356 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00002357 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302358
2359 //VOL-4965: Recover previously Activating ONU during reconciliation.
2360 if dh.device.OperStatus == common.OperStatus_ACTIVATING {
2361 logger.Debugw(ctx, "Reconciling an ONU in previously activating state, perform MIB reset and resume normal start up",
2362 log.Fields{"device-id": dh.DeviceID})
2363 pDevEntry.MutexPersOnuConfig.Lock()
2364 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2365 pDevEntry.MutexPersOnuConfig.Unlock()
2366 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002367 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002368 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002369 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002370 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002371 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
2372 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
2373 // 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 +00002374 // 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 +00002375 // so let's just try to keep it simple ...
2376 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00002377 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002378 if err != nil || device == nil {
2379 //TODO: needs to handle error scenarios
2380 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
2381 return errors.New("Voltha Device not found")
2382 }
2383 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002384
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002385 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002386 return err
mpagenko3af1f032020-06-10 08:53:41 +00002387 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002388 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302389 if !dh.IsReconciling() && !dh.GetSkipOnuConfigEnabled() {
2390 /* this might be a good time for Omci Verify message? */
2391 verifyExec := make(chan bool)
2392 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
2393 dh.device.Id, pDevEntry.PDevOmciCC, false,
2394 true, true) //exclusive and allowFailure (anyway not yet checked)
2395 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002396
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302397 /* give the handler some time here to wait for the OMCi verification result
2398 after Timeout start and try MibUpload FSM anyway
2399 (to prevent stopping on just not supported OMCI verification from ONU) */
2400 select {
2401 case <-time.After(((cmn.CDefaultRetries+1)*otst.CTestRequestOmciTimeout + 1) * time.Second):
2402 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
2403 case testresult := <-verifyExec:
2404 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
2405 case <-dh.deviceDeleteCommChan:
2406 logger.Warnw(ctx, "Deleting device, stopping the omci test activity", log.Fields{"device-id": dh.DeviceID})
2407 return nil
2408 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002409 }
2410
2411 /* In py code it looks earlier (on activate ..)
2412 # Code to Run OMCI Test Action
2413 kwargs_omci_test_action = {
2414 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2415 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2416 }
2417 serial_number = device.serial_number
2418 self._test_request = OmciTestRequest(self.core_proxy,
2419 self.omci_agent, self.device_id,
2420 AniG, serial_number,
2421 self.logical_device_id,
2422 exclusive=False,
2423 **kwargs_omci_test_action)
2424 ...
2425 # Start test requests after a brief pause
2426 if not self._test_request_started:
2427 self._test_request_started = True
2428 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2429 reactor.callLater(tststart, self._test_request.start_collector)
2430
2431 */
2432 /* which is then: in omci_test_request.py : */
2433 /*
2434 def start_collector(self, callback=None):
2435 """
2436 Start the collection loop for an adapter if the frequency > 0
2437
2438 :param callback: (callable) Function to call to collect PM data
2439 """
2440 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2441 if callback is None:
2442 callback = self.perform_test_omci
2443
2444 if self.lc is None:
2445 self.lc = LoopingCall(callback)
2446
2447 if self.default_freq > 0:
2448 self.lc.start(interval=self.default_freq / 10)
2449
2450 def perform_test_omci(self):
2451 """
2452 Perform the initial test request
2453 """
2454 ani_g_entities = self._device.configuration.ani_g_entities
2455 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2456 is not None else None
2457 self._entity_id = ani_g_entities_ids[0]
2458 self.logger.info('perform-test', entity_class=self._entity_class,
2459 entity_id=self._entity_id)
2460 try:
2461 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2462 result = yield self._device.omci_cc.send(frame)
2463 if not result.fields['omci_message'].fields['success_code']:
2464 self.logger.info('Self-Test Submitted Successfully',
2465 code=result.fields[
2466 'omci_message'].fields['success_code'])
2467 else:
2468 raise TestFailure('Test Failure: {}'.format(
2469 result.fields['omci_message'].fields['success_code']))
2470 except TimeoutError as e:
2471 self.deferred.errback(failure.Failure(e))
2472
2473 except Exception as e:
2474 self.logger.exception('perform-test-Error', e=e,
2475 class_id=self._entity_class,
2476 entity_id=self._entity_id)
2477 self.deferred.errback(failure.Failure(e))
2478
2479 */
2480
2481 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002482 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002483
mpagenko1cc3cb42020-07-27 15:24:38 +00002484 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2485 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2486 * 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 +05302487 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002488 */
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302489
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002490 //call MibUploadFSM - transition up to state UlStInSync
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302491 // Breaking this part of code due to sca complexity
2492 err := dh.CheckAndStartMibUploadFsm(ctx, pDevEntry)
2493 return err
2494}
2495
2496func (dh *deviceHandler) CheckAndStartMibUploadFsm(ctx context.Context, pDevEntry *mib.OnuDeviceEntry) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002497 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002498 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002499 if pMibUlFsm.Is(mib.UlStDisabled) {
2500 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2501 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2502 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302503 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002504 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302505 //Determine ONU status and start/re-start MIB Synchronization tasks
2506 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002507 if pDevEntry.IsNewOnu() {
2508 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2509 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2510 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002511 }
Himani Chawla4d908332020-08-31 12:30:20 +05302512 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002513 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2514 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2515 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302516 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002517 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002518 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002519 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002520 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002521 "device-id": dh.DeviceID})
2522 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002523 }
2524 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002525 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2526 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002527 }
2528 return nil
2529}
2530
Holger Hildebrandt68854a82022-09-05 07:00:21 +00002531func (dh *deviceHandler) UpdateInterface(ctx context.Context) error {
mpagenko3af1f032020-06-10 08:53:41 +00002532 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002533 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002534 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302535 logger.Info(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002536
mpagenko900ee4b2020-10-12 11:56:34 +00002537 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2538 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2539 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002540 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002541 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002542 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002543 // abort: system behavior is just unstable ...
2544 return err
2545 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002546 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302547 if !dh.GetDeviceTechProfOnReboot() {
2548 _ = dh.deleteDevicePersistencyData(ctx) //ignore possible errors here and continue, hope is that data is synchronized with new ONU-Up
2549 }
mpagenko900ee4b2020-10-12 11:56:34 +00002550
2551 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002552 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002553 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002554 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002555 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2556 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002557 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002558 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002559
2560 //TODO!!! remove existing traffic profiles
2561 /* from py code, if TP's exist, remove them - not yet implemented
2562 self._tp = dict()
2563 # Let TP download happen again
2564 for uni_id in self._tp_service_specific_task:
2565 self._tp_service_specific_task[uni_id].clear()
2566 for uni_id in self._tech_profile_download_done:
2567 self._tech_profile_download_done[uni_id].clear()
2568 */
2569
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002570 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002571
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002572 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002573
mpagenkoe4782082021-11-25 12:04:26 +00002574 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002575 // abort: system behavior is just unstable ...
2576 return err
2577 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002578 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002579 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002580 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002581 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002582 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2583 OperStatus: voltha.OperStatus_DISCOVERED,
2584 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002585 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002586 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002587 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002588 // abort: system behavior is just unstable ...
2589 return err
2590 }
akashreddykb03dde02025-12-02 10:53:18 +05302591 if dh.GetDeviceTechProfOnReboot() {
2592 logger.Debugw(ctx, "Storing OnuPersData during device-down-indication", log.Fields{"device": dh.DeviceID, "onu-pers-data": dh.pOnuOmciDevice.SOnuPersistentData})
2593 if err := dh.StorePersistentData(ctx); err != nil {
2594 logger.Warnw(ctx, "store persistent data error - Failed to store DownIndication",
2595 log.Fields{"device-id": dh.DeviceID, "err": err})
2596 }
2597 }
mpagenko3af1f032020-06-10 08:53:41 +00002598 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002599 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002600 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002601 return nil
2602}
2603
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002604func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002605 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2606 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2607 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2608 // and using the stop/reset event should never harm
Holger Hildebrandt12609a12022-03-25 13:23:25 +00002609 logger.Debugw(ctx, "resetFsms entered", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002610
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002611 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Praneeth Kumar Nalmasfcdd20b2024-01-24 22:26:39 +05302612 //VOL-5260: During race conditions when adoptDevice has not yet completed
2613 // and deleteDevice is issued , returning error will further prevent clean up
2614 // at rwcore . Returning success for clean up to happen and discovery to happen again.
mpagenko900ee4b2020-10-12 11:56:34 +00002615 if pDevEntry == nil {
mgoudaa797e1c2025-06-24 17:49:42 +05302616 errMsg := fmt.Sprintf("Device entry is not found %s", dh.DeviceID)
2617 logger.Error(ctx, errMsg)
2618 return status.Error(codes.NotFound, errMsg)
mpagenko900ee4b2020-10-12 11:56:34 +00002619 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002620 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002621 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002622 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002623 pDevEntry.MutexOnuImageStatus.RLock()
2624 if pDevEntry.POnuImageStatus != nil {
2625 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002626 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002627 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002628
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002629 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002630 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002631 }
2632 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002633 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002634 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002635 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002636 }
mpagenko101ac942021-11-16 15:01:29 +00002637 //stop any deviceHandler reconcile processing (if running)
2638 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002639 //port lock/unlock FSM's may be active
2640 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002641 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002642 }
2643 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002644 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002645 }
2646 //techProfile related PonAniConfigFsm FSM may be active
2647 if dh.pOnuTP != nil {
2648 // should always be the case here
2649 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002650 if dh.pOnuTP.PAniConfigFsm != nil {
2651 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2652 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002653 }
mpagenko900ee4b2020-10-12 11:56:34 +00002654 }
2655 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002656 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002657 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002658 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002659 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002660 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002661 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002662 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002663 } else {
2664 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002665 }
2666 }
2667 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302668
2669 dh.mutexCollectorFlag.Lock()
2670 logger.Debugw(ctx, "check-collector-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.collectorIsRunning})
2671 if dh.collectorIsRunning {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002672 // Stop collector routine
2673 dh.stopCollector <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302674 dh.collectorIsRunning = false
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002675 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302676 dh.mutexCollectorFlag.Unlock()
2677
2678 dh.mutextAlarmManagerFlag.Lock()
2679 logger.Debugw(ctx, "check-alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
2680 if dh.alarmManagerIsRunning {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302681 dh.stopAlarmManager <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302682 dh.alarmManagerIsRunning = false
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302683 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302684 dh.mutextAlarmManagerFlag.Unlock()
2685
2686 dh.pSelfTestHdlr.SelfTestHandlerLock.Lock()
2687 logger.Debugw(ctx, "check-self-test-control-block-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.pSelfTestHdlr.SelfTestHandlerActive})
2688 if dh.pSelfTestHdlr.SelfTestHandlerActive {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002689 dh.pSelfTestHdlr.StopSelfTestModule <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302690 dh.pSelfTestHdlr.SelfTestHandlerActive = false
Girish Gowdra10123c02021-08-30 11:52:06 -07002691 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302692 dh.pSelfTestHdlr.SelfTestHandlerLock.Unlock()
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302693
Girish Gowdrae95687a2021-09-08 16:30:58 -07002694 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2695
mpagenko80622a52021-02-09 16:53:23 +00002696 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002697 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002698 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002699 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002700 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002701 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002702 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002703 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2704 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2705 // (even though it may also run into direct cancellation, a bit hard to verify here)
2706 // so don't set 'dh.upgradeCanceled = true' here!
2707 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2708 }
mpagenko38662d02021-08-11 09:45:19 +00002709 }
mpagenko80622a52021-02-09 16:53:23 +00002710
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002711 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002712 return nil
2713}
2714
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302715//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002716func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2717 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 +05302718
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002719 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002720 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002721 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002722 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002723 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002724 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002725 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002726
mpagenkoa40e99a2020-11-17 13:50:39 +00002727 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2728 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2729 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2730 * disable/enable toggling here to allow traffic
2731 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2732 * like the py comment says:
2733 * # start by locking all the unis till mib sync and initial mib is downloaded
2734 * # this way we can capture the port down/up events when we are ready
2735 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302736
mpagenkoa40e99a2020-11-17 13:50:39 +00002737 // Init Uni Ports to Admin locked state
2738 // *** should generate UniLockStateDone event *****
2739 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002740 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002741 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002742 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002743 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002744 }
2745}
2746
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302747//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002748func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2749 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302750 /* Mib download procedure -
2751 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2752 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002753 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002754 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002755 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002756 return
2757 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002758 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302759 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002760 if pMibDlFsm.Is(mib.DlStDisabled) {
2761 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2762 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 +05302763 // maybe try a FSM reset and then again ... - TODO!!!
2764 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002765 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302766 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002767 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2768 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302769 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002770 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302771 //Begin MIB data download (running autonomously)
2772 }
2773 }
2774 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002775 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002776 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302777 // maybe try a FSM reset and then again ... - TODO!!!
2778 }
2779 /***** Mib download started */
2780 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002781 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302782 }
2783}
2784
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302785//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002786func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302787 logger.Info(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002788 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
2789 if pDevEntry == nil {
2790 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2791 return
2792 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002793 if !dh.IsReconciling() {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002794 logger.Debugw(ctx, "call DeviceUpdate and DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002795 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002796 // update device info in core
2797 pDevEntry.MutexPersOnuConfig.RLock()
2798 dh.device.Vendor = pDevEntry.SOnuPersistentData.PersVendorID
2799 dh.device.VendorId = pDevEntry.SOnuPersistentData.PersVendorID
2800 dh.device.Model = pDevEntry.SOnuPersistentData.PersVersion
2801 pDevEntry.MutexPersOnuConfig.RUnlock()
2802 dh.logicalDeviceID = dh.DeviceID
2803 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
2804 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2805 }
2806 // update device state in core
mpagenko15ff4a52021-03-02 10:09:20 +00002807 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2808 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2809 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2810 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002811 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002812 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002813 ConnStatus: voltha.ConnectStatus_REACHABLE,
2814 OperStatus: voltha.OperStatus_ACTIVE,
2815 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302816 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002817 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302818 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002819 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302820 }
2821 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302822 logger.Info(ctx, "reconciling - don't notify core about updated device info and DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002823 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302824 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002825 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002826
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002827 if !dh.GetCollectorIsRunning() {
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002828 var waitForOmciProcessor sync.WaitGroup
2829 waitForOmciProcessor.Add(1)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002830 // Start PM collector routine
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002831 go dh.StartCollector(ctx, &waitForOmciProcessor)
2832 waitForOmciProcessor.Wait()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002833 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002834 if !dh.GetAlarmManagerIsRunning(ctx) {
2835 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002836 }
2837
Girish Gowdrae95687a2021-09-08 16:30:58 -07002838 // Start flow handler routines per UNI
2839 for _, uniPort := range dh.uniEntityMap {
2840 // only if this port was enabled for use by the operator at startup
2841 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2842 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2843 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2844 }
2845 }
2846 }
2847
Girish Gowdrae0140f02021-02-02 16:55:09 -08002848 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002849 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002850 // There is no way we should be landing here, but if we do then
2851 // there is nothing much we can do about this other than log error
2852 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2853 }
2854
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002855 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002856
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002857 pDevEntry.MutexPersOnuConfig.RLock()
2858 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2859 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302860 logger.Warn(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002861 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002862 dh.mutexForDisableDeviceRequested.Lock()
2863 dh.disableDeviceRequested = true
2864 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002865 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002866 // reconcilement will be continued after ani config is done
2867 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002868 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002869 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002870 dh.mutexForDisableDeviceRequested.RLock()
2871 if !dh.disableDeviceRequested {
2872 if dh.pUnlockStateFsm == nil {
2873 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2874 } else { //UnlockStateFSM already init
2875 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2876 dh.runUniLockFsm(ctx, false)
2877 }
2878 dh.mutexForDisableDeviceRequested.RUnlock()
2879 } else {
2880 dh.mutexForDisableDeviceRequested.RUnlock()
2881 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002882 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302883 }
2884}
2885
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302886//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002887func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2888 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302889
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002890 if !dh.IsReconciling() {
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302891 // Check if TPs are available post device reboot. If TPs are available start processing them and configure flows
2892 if dh.GetDeviceTechProfOnReboot() {
2893 if dh.CheckForDeviceTechProf(ctx) {
2894 go dh.DeviceFlowConfigOnReboot(ctx)
2895 }
2896 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002897 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002898 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002899 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2900 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002901 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002902 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002903 return
2904 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002905 pDevEntry.MutexPersOnuConfig.Lock()
2906 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2907 pDevEntry.MutexPersOnuConfig.Unlock()
2908 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002909 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002910 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002911 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302912 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302913 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 +00002914 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002915 dh.ReconcileDeviceTechProf(ctx)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302916
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002917 // reconcilement will be continued after ani config is done
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302918
Himani Chawla26e555c2020-08-31 12:30:20 +05302919 }
2920}
2921
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302922//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002923func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002924 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002925 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002926
mpagenko44bd8362021-11-15 11:40:05 +00002927 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002928 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002929 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002930 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002931 OperStatus: voltha.OperStatus_UNKNOWN,
2932 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002933 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002934 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002935 }
2936
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002937 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002938 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002939 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002940
2941 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002942 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002943
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002944 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002945 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002946 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002947 return
2948 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002949 pDevEntry.MutexPersOnuConfig.Lock()
2950 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2951 pDevEntry.MutexPersOnuConfig.Unlock()
2952 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002953 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002954 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002955 }
mpagenko900ee4b2020-10-12 11:56:34 +00002956}
2957
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302958//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002959func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002960 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002961 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002962 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002963 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002964 ConnStatus: voltha.ConnectStatus_REACHABLE,
2965 OperStatus: voltha.OperStatus_ACTIVE,
2966 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002967 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002968 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002969 }
2970
dbainbri4d3a0dc2020-12-02 00:33:42 +00002971 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002972 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002973 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002974 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002975
2976 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002977 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002978
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002979 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002980 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002981 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002982 return
2983 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002984 pDevEntry.MutexPersOnuConfig.Lock()
2985 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2986 pDevEntry.MutexPersOnuConfig.Unlock()
2987 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002988 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002989 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002990 }
mpagenko900ee4b2020-10-12 11:56:34 +00002991}
2992
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302993//nolint:unparam
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002994func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2995 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2996 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002997 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002998 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002999 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003000 OperStatus: voltha.OperStatus_FAILED,
3001 }); err != nil {
3002 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
3003 }
3004}
3005
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003006func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
3007 if devEvent == cmn.OmciAniConfigDone {
3008 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003009 // attention: the device reason update is done based on ONU-UNI-Port related activity
3010 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003011 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00003012 // 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 +00003013 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05303014 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003015 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00003016 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
3017 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
3018 dh.mutexReconcilingFirstPassFlag.Lock()
3019 if dh.reconcilingFirstPass {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303020 logger.Info(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00003021 dh.reconcilingFirstPass = false
3022 go dh.ReconcileDeviceFlowConfig(ctx)
3023 }
3024 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00003025 }
3026 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003027 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003028 // attention: the device reason update is done based on ONU-UNI-Port related activity
3029 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003030 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00003031 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
3032 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00003033 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003034 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303035}
3036
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003037func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003038 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003039 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05303040 // attention: the device reason update is done based on ONU-UNI-Port related activity
3041 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05303042
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003043 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
3044 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00003045 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00003046 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00003047 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00003048 }
3049 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003050 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00003051 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00003052 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003053 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303054 }
mpagenkof1fc3862021-02-16 10:09:52 +00003055
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003056 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00003057 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003058 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003059 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003060 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00003061 }
3062 } else {
3063 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003064 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003065 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303066}
3067
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303068// DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003069func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05303070 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003071 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003072 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003073 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003074 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003075 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00003076 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003077 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00003078 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003079 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003080 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003081 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003082 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003083 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003084 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003085 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003086 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003087 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00003088 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003089 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00003090 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003091 case cmn.UniEnableStateFailed:
3092 {
3093 dh.processUniEnableStateFailedEvent(ctx, devEvent)
3094 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003095 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00003096 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003097 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00003098 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003099 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00003100 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003101 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00003102 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003103 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00003104 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003105 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00003106 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003107 default:
3108 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003109 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003110 }
3111 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003112}
3113
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003114func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003115 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07003116 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05303117 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003118 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003119 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003120 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05303121 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003122 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003123 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003124 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 +00003125 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003126 //store UniPort with the System-PortNumber key
3127 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003128 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003129 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003130 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003131 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003132 } //error logging already within UniPort method
3133 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303134 logger.Warn(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003135 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003136 }
3137 }
3138}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003139
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003140func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
3141 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003142 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003143 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003144 return
3145 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07003146 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003147 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003148 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
3149 for _, mgmtEntityID := range pptpInstKeys {
3150 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003151 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003152 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
3153 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003154 }
3155 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003156 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003157 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003158 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003159 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
3160 for _, mgmtEntityID := range veipInstKeys {
3161 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003162 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003163 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
3164 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003165 }
3166 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003167 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003168 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003169 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03003170 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
3171 for _, mgmtEntityID := range potsInstKeys {
3172 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003173 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003174 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
3175 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03003176 }
3177 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003178 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03003179 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07003180 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003181 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003182 return
3183 }
3184
mpagenko2c3f6c52021-11-23 11:22:10 +00003185 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
3186 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
3187 // 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 -07003188 dh.flowCbChan = make([]chan FlowCb, uniCnt)
3189 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
3190 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00003191 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
3192 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303193 dh.chUniVlanConfigOnRebootDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003194 for i := 0; i < int(uniCnt); i++ {
3195 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00003196 dh.stopFlowMonitoringRoutine[i] = make(chan bool, 1)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003197 }
3198}
3199
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003200// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
3201func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003202 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05303203 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003204 // with following remark:
3205 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
3206 // # load on the core
3207
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003208 // 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 +00003209
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003210 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00003211 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003212 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
3213 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
mgoudad611f4c2025-10-30 14:49:27 +05303214 uniPort.SetOperState(common.OperStatus_ACTIVE)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003215 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003216 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003217 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04003218 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003219 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003220 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003221 PortNo: port.PortNo,
3222 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04003223 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003224 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 -04003225 }
3226 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003227 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303228 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003229 }
mpagenko3af1f032020-06-10 08:53:41 +00003230 }
3231 }
3232}
3233
3234// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003235func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
3236 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00003237 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
3238 for uniNo, uniPort := range dh.uniEntityMap {
3239 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02003240
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003241 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
3242 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
mgoudad611f4c2025-10-30 14:49:27 +05303243 uniPort.SetOperState(common.OperStatus_UNKNOWN)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003244 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003245 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003246 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04003247 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003248 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003249 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003250 PortNo: port.PortNo,
3251 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04003252 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003253 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 -04003254 }
3255 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003256 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303257 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003258 }
3259
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003260 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003261 }
3262}
3263
3264// ONU_Active/Inactive announcement on system KAFKA bus
3265// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
mgoudad611f4c2025-10-30 14:49:27 +05303266func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState common.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003267 var de voltha.DeviceEvent
3268 eventContext := make(map[string]string)
3269 //Populating event context
3270 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04003271 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003272 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003273 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003274 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00003275 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 +00003276 }
3277 oltSerialNumber := parentDevice.SerialNumber
3278
3279 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
3280 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
3281 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05303282 eventContext["olt-serial-number"] = oltSerialNumber
3283 eventContext["device-id"] = aDeviceID
3284 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03003285 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003286 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
3287 deviceEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00003288 eventContext["vendor-id"] = deviceEntry.SOnuPersistentData.PersVendorID
3289 eventContext["model"] = deviceEntry.SOnuPersistentData.PersVersion
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003290 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
3291 deviceEntry.MutexPersOnuConfig.RUnlock()
3292 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003293 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03003294 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
3295 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
3296 } else {
3297 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
3298 log.Fields{"device-id": aDeviceID})
3299 return
3300 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003301
3302 /* Populating device event body */
3303 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05303304 de.ResourceId = aDeviceID
3305 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003306 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
3307 de.Description = fmt.Sprintf("%s Event - %s - %s",
3308 cEventObjectType, cOnuActivatedEvent, "Raised")
3309 } else {
3310 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
3311 de.Description = fmt.Sprintf("%s Event - %s - %s",
3312 cEventObjectType, cOnuActivatedEvent, "Cleared")
3313 }
3314 /* Send event to KAFKA */
kesavand510a31c2022-03-16 17:12:12 +05303315 if err := dh.EventProxy.SendDeviceEventWithKey(ctx, &de, equipment, pon, raisedTs, aDeviceID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003316 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05303317 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003318 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303319 logger.Infow(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05303320 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003321}
3322
Himani Chawla4d908332020-08-31 12:30:20 +05303323// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003324func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303325 chLSFsm := make(chan cmn.Message, 2)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003326 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05303327 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003328 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003329 sFsmName = "LockStateFSM"
3330 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003331 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003332 sFsmName = "UnLockStateFSM"
3333 }
mpagenko3af1f032020-06-10 08:53:41 +00003334
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003335 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00003336 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003337 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00003338 return
3339 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003340 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003341 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05303342 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003343 dh.pLockStateFsm = pLSFsm
3344 } else {
3345 dh.pUnlockStateFsm = pLSFsm
3346 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003347 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003348 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003349 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003350 }
3351}
3352
3353// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00003354func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003355 /* Uni Port lock/unlock procedure -
3356 ***** should run via 'adminDone' state and generate the argument requested event *****
3357 */
3358 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05303359 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003360 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003361 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
3362 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003363 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
3364 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003365 }
3366 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003367 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003368 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
3369 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003370 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
3371 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003372 }
3373 }
3374 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003375 if pLSStatemachine.Is(uniprt.UniStDisabled) {
3376 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003377 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003378 // maybe try a FSM reset and then again ... - TODO!!!
3379 } else {
3380 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003381 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003382 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003383 }
3384 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003385 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003386 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003387 // maybe try a FSM reset and then again ... - TODO!!!
3388 }
3389 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003390 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003391 // maybe try a FSM reset and then again ... - TODO!!!
3392 }
3393}
3394
mpagenko80622a52021-02-09 16:53:23 +00003395// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00003396// precondition: lockUpgradeFsm is already locked from caller of this function
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303397//
3398//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003399func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303400 chUpgradeFsm := make(chan cmn.Message, 2)
mpagenko80622a52021-02-09 16:53:23 +00003401 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003402 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003403 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003404 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303405 return fmt.Errorf("no valid omciCC - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003406 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003407 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00003408 sFsmName, chUpgradeFsm)
3409 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003410 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00003411 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003412 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
3413 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003414 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00003415 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303416 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003417 }
mpagenko59862f02021-10-11 08:53:18 +00003418 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00003419 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
3420 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00003421 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
3422 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00003423 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003424 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003425 } else {
3426 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003427 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003428 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303429 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003430 }
3431 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003432 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003433 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303434 return fmt.Errorf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003435 }
3436 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003437 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303438 return fmt.Errorf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003439 }
3440 return nil
3441}
3442
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003443// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
3444func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00003445 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003446 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003447 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00003448 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
3449 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00003450 dh.pLastUpgradeImageState = apImageState
3451 dh.lockUpgradeFsm.Unlock()
3452 //signal upgradeFsm removed using non-blocking channel send
3453 select {
3454 case dh.upgradeFsmChan <- struct{}{}:
3455 default:
3456 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003457 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003458 }
mpagenko80622a52021-02-09 16:53:23 +00003459}
3460
mpagenko15ff4a52021-03-02 10:09:20 +00003461// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3462func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003463 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003464 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003465 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003466 return
3467 }
3468
3469 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003470 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003471 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003472 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3473 dh.lockUpgradeFsm.RUnlock()
3474 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3475 return
3476 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003477 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003478 if pUpgradeStatemachine != nil {
3479 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3480 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003481 UpgradeState := pUpgradeStatemachine.Current()
3482 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3483 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3484 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003485 // 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 +00003486 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003487 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3488 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003489 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003490 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003491 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003492 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3493 dh.upgradeCanceled = true
3494 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3495 }
mpagenko15ff4a52021-03-02 10:09:20 +00003496 return
3497 }
mpagenko59862f02021-10-11 08:53:18 +00003498 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003499 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3500 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003501 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003502 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003503 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3504 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003505 return
3506 }
3507 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003508 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003509 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003510 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3511 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003512 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3513 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003514 return
3515 }
3516 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003517 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003518 }
3519 } else {
3520 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 +00003521 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003522 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3523 dh.upgradeCanceled = true
3524 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3525 }
mpagenko1f8e8822021-06-25 14:10:21 +00003526 }
mpagenko15ff4a52021-03-02 10:09:20 +00003527 return
3528 }
mpagenko59862f02021-10-11 08:53:18 +00003529 dh.lockUpgradeFsm.RUnlock()
3530 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3531 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003532 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3533 dh.upgradeCanceled = true
3534 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3535 }
mpagenko59862f02021-10-11 08:53:18 +00003536 return
3537 }
3538 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3539 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3540 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3541 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3542 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3543 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3544 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003545 }
mpagenko15ff4a52021-03-02 10:09:20 +00003546 }
3547 }
3548 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003549 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003550 }
mpagenko59862f02021-10-11 08:53:18 +00003551 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003552}
3553
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303554// SetBackend provides a DB backend for the specified path on the existing KV client
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003555func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003556
3557 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003558 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003559 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003560 kvbackend := &db.Backend{
3561 Client: dh.pOpenOnuAc.kvClient,
3562 StoreType: dh.pOpenOnuAc.KVStoreType,
3563 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003564 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003565 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3566 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003567
mpagenkoaf801632020-07-03 10:00:42 +00003568 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003569}
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303570
3571//nolint:unparam
khenaidoo7d3c5582021-08-11 18:09:44 -04003572func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303573 loMatchPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003574
mpagenkodff5dda2020-08-28 11:52:01 +00003575 for _, field := range flow.GetOfbFields(apFlowItem) {
3576 switch field.Type {
3577 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3578 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003579 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003580 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3581 }
mpagenko01e726e2020-10-23 09:45:29 +00003582 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003583 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3584 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303585 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003586 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303587 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3588 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003589 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3590 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003591 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003592 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303593 return
mpagenkodff5dda2020-08-28 11:52:01 +00003594 }
3595 }
mpagenko01e726e2020-10-23 09:45:29 +00003596 */
mpagenkodff5dda2020-08-28 11:52:01 +00003597 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3598 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303599 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003600 loMatchVlanMask := uint16(field.GetVlanVidMask())
mgoudad611f4c2025-10-30 14:49:27 +05303601 if *loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) ||
3602 loMatchVlanMask != uint16(of.OfpVlanId_OFPVID_PRESENT) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303603 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003604 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003605 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303606 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003607 }
3608 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3609 {
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303610 *loMatchPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003611 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303612 "PCP": loMatchPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003613 }
3614 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3615 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003616 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003617 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3618 }
3619 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3620 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003621 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003622 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3623 }
3624 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3625 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003626 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003627 "IPv4-DST": field.GetIpv4Dst()})
3628 }
3629 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3630 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003631 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003632 "IPv4-SRC": field.GetIpv4Src()})
3633 }
3634 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3635 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003636 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003637 "Metadata": field.GetTableMetadata()})
3638 }
3639 /*
3640 default:
3641 {
3642 //all other entires ignored
3643 }
3644 */
3645 }
3646 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303647}
mpagenkodff5dda2020-08-28 11:52:01 +00003648
khenaidoo7d3c5582021-08-11 18:09:44 -04003649func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003650 for _, action := range flow.GetActions(apFlowItem) {
3651 switch action.Type {
3652 /* not used:
3653 case of.OfpActionType_OFPAT_OUTPUT:
3654 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003655 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003656 "Output": action.GetOutput()})
3657 }
3658 */
3659 case of.OfpActionType_OFPAT_PUSH_VLAN:
3660 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003661 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003662 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3663 }
3664 case of.OfpActionType_OFPAT_SET_FIELD:
3665 {
3666 pActionSetField := action.GetSetField()
3667 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003668 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003669 "OxcmClass": pActionSetField.Field.OxmClass})
3670 }
3671 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303672 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003673 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303674 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003675 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303676 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003677 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303678 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003679 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003680 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003681 "Type": pActionSetField.Field.GetOfbField().Type})
3682 }
3683 }
3684 /*
3685 default:
3686 {
3687 //all other entires ignored
3688 }
3689 */
3690 }
3691 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303692}
3693
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303694// addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003695func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003696 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
mgoudad611f4c2025-10-30 14:49:27 +05303697 var loSetVlan = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3698 var loMatchVlan = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303699 var loSetPcp uint8
3700 var loMatchPcp uint8 = 8 // could the const 'cPrioDoNotFilter' be used from omci_vlan_config.go ?
Himani Chawla26e555c2020-08-31 12:30:20 +05303701 var loIPProto uint32
3702 /* the TechProfileId is part of the flow Metadata - compare also comment within
3703 * OLT-Adapter:openolt_flowmgr.go
3704 * Metadata 8 bytes:
3705 * Most Significant 2 Bytes = Inner VLAN
3706 * Next 2 Bytes = Tech Profile ID(TPID)
3707 * Least Significant 4 Bytes = Port ID
3708 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3709 * subscriber related flows.
3710 */
3711
dbainbri4d3a0dc2020-12-02 00:33:42 +00003712 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303713 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003714 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003715 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003716 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303717 }
mpagenko551a4d42020-12-08 18:09:20 +00003718 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003719 loCookie := apFlowItem.GetCookie()
3720 loCookieSlice := []uint64{loCookie}
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303721 loInnerCvlan := flow.GetInnerTagFromWriteMetaData(ctx, metadata)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003722 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303723 "TechProf-Id": loTpID, "cookie": loCookie, "innerCvlan": loInnerCvlan})
Himani Chawla26e555c2020-08-31 12:30:20 +05303724
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303725 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loMatchPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003726 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303727 if loIPProto == 2 {
3728 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3729 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003730 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003731 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303732 return nil
3733 }
mpagenko01e726e2020-10-23 09:45:29 +00003734 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003735 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003736
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303737 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) && (loMatchPcp == 8) &&
3738 loInnerCvlan == uint16(of.OfpVlanId_OFPVID_NONE) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003739 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003740 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003741 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3742 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3743 //TODO!!: Use DeviceId within the error response to rwCore
3744 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003745 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003746 }
3747 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003748 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003749 loSetVlan = loMatchVlan //both 'transparent' (copy any)
Abhilash Laxmeshwarf15a0d02022-08-08 11:09:32 +05303750 } else if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) &&
3751 loInnerCvlan != uint16(of.OfpVlanId_OFPVID_NONE) {
3752 loSetVlan = loMatchVlan
3753 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 +00003754 } else {
3755 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3756 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3757 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303758 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003759 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003760 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003761 }
mpagenko9a304ea2020-12-16 15:54:01 +00003762
khenaidoo42dcdfd2021-10-19 17:34:12 -04003763 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003764 if apFlowMetaData != nil {
3765 meter = apFlowMetaData.Meters[0]
3766 }
mpagenkobc4170a2021-08-17 16:42:10 +00003767 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3768 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3769 // when different rules are requested concurrently for the same uni
3770 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3771 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3772 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003773 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3774 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003775 //SetUniFlowParams() may block on some rule that is suspended-to-add
3776 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003777 // Also the error is returned to caller via response channel
3778 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303779 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, false, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003780 dh.lockVlanConfig.RUnlock()
3781 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003782 return
mpagenkodff5dda2020-08-28 11:52:01 +00003783 }
mpagenkobc4170a2021-08-17 16:42:10 +00003784 dh.lockVlanConfig.RUnlock()
3785 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003786 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303787 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, cmn.OmciVlanFilterAddDone, false, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003788 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003789 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003790 if err != nil {
3791 *respChan <- err
3792 }
mpagenko01e726e2020-10-23 09:45:29 +00003793}
3794
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303795// removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003796func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003797 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3798 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3799 //no extra check is done on the rule parameters
3800 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3801 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3802 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3803 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003804 // - 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 +00003805 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003806 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003807
3808 /* TT related temporary workaround - should not be needed anymore
3809 for _, field := range flow.GetOfbFields(apFlowItem) {
3810 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3811 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003812 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003813 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3814 if loIPProto == 2 {
3815 // 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 +00003816 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003817 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003818 return nil
3819 }
3820 }
3821 } //for all OfbFields
3822 */
3823
mpagenko9a304ea2020-12-16 15:54:01 +00003824 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003825 dh.lockVlanConfig.RLock()
3826 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003827 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3828 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003829 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3830 return
mpagenko01e726e2020-10-23 09:45:29 +00003831 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003832 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003833 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003834 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003835 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003836 // Push response on the response channel
3837 if respChan != nil {
3838 // 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
3839 select {
3840 case *respChan <- nil:
3841 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3842 default:
3843 }
3844 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003845 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003846}
3847
Himani Chawla26e555c2020-08-31 12:30:20 +05303848// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003849// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003850// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003851func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303852 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 +05303853 chVlanFilterFsm := make(chan cmn.Message, 2)
mpagenkodff5dda2020-08-28 11:52:01 +00003854
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003855 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003856 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003857 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3858 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003859 }
3860
Sridhar Ravindra2f86efb2024-12-06 11:02:10 +05303861 if dh.pDeviceStateFsm.Current() == devStDown {
3862 logger.Warnw(ctx, "UniVlanConfigFsm : aborting, device state down", log.Fields{"device-id": dh.DeviceID})
3863 return fmt.Errorf("device state down for device-id %x - aborting", dh.DeviceID)
3864 }
3865
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003866 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3867 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303868 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, lastFlowToReconcile, lastFlowToConfOnReboot, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003869 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003870 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3871 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003872 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3873 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003874 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003875 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3876 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003877 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3878 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003879 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003880 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303881 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003882 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003883 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3884 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003885 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003886 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003887 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3888 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003889 }
3890 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003891 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003892 "device-id": dh.DeviceID})
3893 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003894 }
3895 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003896 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003897 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3898 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003899 }
3900 return nil
3901}
3902
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303903// VerifyVlanConfigRequest checks on existence of a given uniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003904// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003905func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003906 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003907 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003908 for _, uniPort := range dh.uniEntityMap {
3909 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003910 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003911 pCurrentUniPort = uniPort
3912 break //found - end search loop
3913 }
3914 }
3915 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003916 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003917 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003918 return
3919 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003920 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003921}
3922
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303923// VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003924func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003925 //TODO!! verify and start pending flow configuration
3926 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3927 //but execution was set to 'on hold' as first the TechProfile config had to be applied
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303928 logger.Info(ctx, "Verifying UniVlanConfig Request", log.Fields{"device-id": dh.DeviceID, "UniPort": apUniPort.PortNo, "techprofile-id": aTpID})
mpagenkof1fc3862021-02-16 10:09:52 +00003929 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003930 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003931 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003932 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003933 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003934 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003935 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003936 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003937 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3938 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003939 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003940 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003941 } else {
3942 /***** UniVlanConfigFsm continued */
3943 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003944 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3945 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003946 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003947 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3948 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003949 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003950 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003951 } else {
3952 /***** UniVlanConfigFsm continued */
3953 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003954 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3955 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003956 }
mpagenkodff5dda2020-08-28 11:52:01 +00003957 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003958 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003959 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3960 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003961 }
3962 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003963 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 +00003964 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3965 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003966 }
3967 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003968 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003969 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003970 }
mpagenkof1fc3862021-02-16 10:09:52 +00003971 } else {
3972 dh.lockVlanConfig.RUnlock()
3973 }
mpagenkodff5dda2020-08-28 11:52:01 +00003974}
3975
Akash Soni3de0e062024-12-11 16:37:26 +05303976// handleAniConfigFSMFailure handles the failure of the ANI config FSM by resetting the VLAN filter FSM
3977func (dh *deviceHandler) HandleAniConfigFSMFailure(ctx context.Context, uniID uint8) {
3978 dh.lockVlanConfig.Lock()
3979 defer dh.lockVlanConfig.Unlock()
3980
3981 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniID]; exist {
3982 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
3983 if pVlanFilterStatemachine != nil {
3984 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
3985 logger.Warnw(ctx, "Failed to reset UniVlanConfigFsm", log.Fields{
3986 "err": err, "device-id": dh.DeviceID, "UniPort": uniID, "FsmState": pVlanFilterStatemachine.Current(),
3987 })
3988 } else {
3989 logger.Infow(ctx, "Successfully reset UniVlanConfigFsm", log.Fields{
3990 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID, "UniPort": uniID,
3991 })
3992 }
3993 } else {
3994 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no reset performed", log.Fields{
3995 "device-id": dh.DeviceID, "UniPort": uniID,
3996 })
3997 }
3998 } else {
3999 logger.Debugw(ctx, "No UniVlanConfigFsm found for the UNI ID", log.Fields{
4000 "device-id": dh.DeviceID, "UniPort": uniID,
4001 })
4002 }
4003}
4004
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304005// RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00004006// 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 +00004007func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00004008 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004009 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00004010 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00004011 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004012 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00004013 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00004014}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004015
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304016// startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004017func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00004018 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
4019 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
4020 // obviously then parallel processing on the cancel must be avoided
4021 // deadline context to ensure completion of background routines waited for
4022 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
4023 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
4024 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05304025 defer cancel() // Ensure cancel is called to release resources
mpagenkof1fc3862021-02-16 10:09:52 +00004026
Akash Soni840f8d62024-12-11 19:37:06 +05304027 err := aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
4028 if err != nil {
4029 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID})
4030 return err
4031 }
4032 return nil
mpagenkof1fc3862021-02-16 10:09:52 +00004033}
4034
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304035// StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
4036// available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004037func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
4038 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004039
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004040 if dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304041 logger.Info(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004042 return nil
4043 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004044 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004045
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004046 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004047 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004048 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
4049 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004050 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004051 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004052
mpagenkof1fc3862021-02-16 10:09:52 +00004053 if aWriteToKvStore {
4054 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
4055 }
4056 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004057}
4058
dbainbri4d3a0dc2020-12-02 00:33:42 +00004059func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004060 defer cancel() //ensure termination of context (may be pro forma)
4061 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00004062 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004063 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004064}
4065
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304066// ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
4067//
4068// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
mpagenkoe4782082021-11-25 12:04:26 +00004069func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
4070 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
4071 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
4072 dh.mutexDeviceReason.Lock()
4073 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004074 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004075 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04004076 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004077 DeviceId: dh.DeviceID,
4078 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04004079 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00004080 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004081 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004082 return err
4083 }
mpagenkoe4782082021-11-25 12:04:26 +00004084 } else {
4085 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 +00004086 }
mpagenkoe4782082021-11-25 12:04:26 +00004087 dh.deviceReason = deviceReason
4088 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
4089 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004090 return nil
4091}
4092
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004093func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
4094 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004095 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004096 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4097 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004098 }
mpagenkof1fc3862021-02-16 10:09:52 +00004099 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004100}
4101
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05304102func (dh *deviceHandler) UpdateRebootPersData(ctx context.Context, flag bool) {
4103 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
4104 if pDevEntry != nil {
4105 pDevEntry.MutexPersOnuConfig.Lock()
4106 pDevEntry.SOnuPersistentData.PersRebootInProgress = flag
4107 pDevEntry.MutexPersOnuConfig.Unlock()
4108 } else {
4109 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4110 }
4111}
4112
4113func (dh *deviceHandler) GetPersRebootFlag(ctx context.Context) bool {
4114 rebootFlag := false
4115 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
4116 if pDevEntry != nil {
4117 pDevEntry.MutexPersOnuConfig.RLock()
4118 rebootFlag = pDevEntry.SOnuPersistentData.PersRebootInProgress
4119 pDevEntry.MutexPersOnuConfig.RUnlock()
4120 } else {
4121 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4122 }
4123 return rebootFlag
4124}
4125
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004126// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03004127// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004128func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
4129 dh.lockDevice.RLock()
4130 defer dh.lockDevice.RUnlock()
4131 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004132 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004133 }
4134 return 0, errors.New("error-fetching-uni-port")
4135}
Girish Gowdrae09a6202021-01-12 18:10:59 -08004136
4137// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004138func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4139 var errorsList []error
4140 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 -08004141
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004142 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
4143 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
4144 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
4145
4146 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
4147 // successfully.
4148 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
4149 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
4150 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004151 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 -08004152 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08004153 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004154 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004155 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08004156}
4157
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004158func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4159 var err error
4160 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004161 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004162
4163 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004164 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004165 errorsList = append(errorsList, err)
4166 }
4167 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004168 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00004169
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004170 return errorsList
4171}
4172
4173func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4174 var err error
4175 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004176 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004177 // Check if group metric related config is updated
4178 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004179 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
4180 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
4181 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004182
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004183 if ok && m.Frequency != v.GroupFreq {
4184 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004185 errorsList = append(errorsList, err)
4186 }
4187 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004188 if ok && m.Enabled != v.Enabled {
4189 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004190 errorsList = append(errorsList, err)
4191 }
4192 }
4193 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004194 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004195 return errorsList
4196}
4197
4198func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4199 var err error
4200 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004201 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004202 // Check if standalone metric related config is updated
4203 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004204 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
4205 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
4206 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004207
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004208 if ok && m.Frequency != v.SampleFreq {
4209 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004210 errorsList = append(errorsList, err)
4211 }
4212 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004213 if ok && m.Enabled != v.Enabled {
4214 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004215 errorsList = append(errorsList, err)
4216 }
4217 }
4218 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004219 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004220 return errorsList
4221}
4222
4223// nolint: gocyclo
Girish Gowdraf7d82d02022-04-26 16:18:35 -07004224func (dh *deviceHandler) StartCollector(ctx context.Context, waitForOmciProcessor *sync.WaitGroup) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004225 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
bseeniva596a5222026-01-23 19:26:11 +05304226 dh.RLockMutexDeletionInProgressFlag()
4227 if dh.GetDeletionInProgress() {
4228 logger.Warnw(ctx, "Device deletion in progress - avoid starting metrics collector routine", log.Fields{"device-id": dh.device.Id})
4229 dh.RUnlockMutexDeletionInProgressFlag()
4230 return
4231 }
4232 // Set collectorIsRunning flag to true while still holding deviceDeletionFlag lock,
4233 // to avoid potential race condition where resetFsm from DeleteDevice might avoid stopping the collector routine if this flag is not yet set
4234 dh.setCollectorIsRunning(true)
4235 dh.RUnlockMutexDeletionInProgressFlag()
Girish Gowdrae09a6202021-01-12 18:10:59 -08004236
4237 // Start routine to process OMCI GET Responses
Girish Gowdraf7d82d02022-04-26 16:18:35 -07004238 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx, waitForOmciProcessor)
Himani Chawla43f95ff2021-06-03 00:24:12 +05304239 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004240 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004241 // Initialize the next metric collection time.
4242 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
4243 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004244 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
praneeth nalmas808f43a2023-05-14 12:54:34 +05304245 statsCollectionticker := time.NewTicker((pmmgr.FrequencyGranularity) * time.Second)
4246 defer statsCollectionticker.Stop()
Girish Gowdrae09a6202021-01-12 18:10:59 -08004247 for {
praneeth nalmas808f43a2023-05-14 12:54:34 +05304248
Girish Gowdrae09a6202021-01-12 18:10:59 -08004249 select {
4250 case <-dh.stopCollector:
4251 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004252 // Stop the L2 PM FSM
4253 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004254 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
4255 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
4256 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004257 }
4258 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004259 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004260 }
4261 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004262 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
4263 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07004264 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004265 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
4266 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07004267 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08004268
Girish Gowdrae09a6202021-01-12 18:10:59 -08004269 return
praneeth nalmas808f43a2023-05-14 12:54:34 +05304270 case <-statsCollectionticker.C: // Check every FrequencyGranularity to see if it is time for collecting metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004271 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
4272 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
4273 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
4274 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08004275 // Update the next metric collection time.
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004276 prevInternal := dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime
4277 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = prevInternal.Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004278 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004279 } else {
4280 if dh.pmConfigs.Grouped { // metrics are managed as a group
4281 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004282 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08004283
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004284 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
4285 // 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 -08004286 // 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 +00004287 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
4288 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004289 }
4290 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004291 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
4292 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
4293 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
4294 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004295 }
4296 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004297 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004298
4299 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004300 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
4301 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
4302 // 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 -08004303 // 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 +00004304 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004305 prevInternal := g.NextCollectionInterval
4306 g.NextCollectionInterval = prevInternal.Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004307 }
4308 }
4309 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004310 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
4311 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
4312 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004313 prevInternal := m.NextCollectionInterval
4314 m.NextCollectionInterval = prevInternal.Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004315 }
4316 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004317 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004318 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04004319 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004320 } */
4321 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08004322 }
4323 }
4324}
kesavandfdf77632021-01-26 23:40:33 -05004325
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304326//nolint:unparam
Akash Soni3c176c62024-12-04 13:30:43 +05304327func (dh *deviceHandler) setOnuOffloadStats(ctx context.Context, config *extension.AppOffloadOnuConfig) *extension.SingleSetValueResponse {
4328
4329 singleValResp := extension.SingleSetValueResponse{
4330 Response: &extension.SetValueResponse{
4331 Status: extension.SetValueResponse_OK,
4332 },
4333 }
4334
4335 return &singleValResp
4336}
4337
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004338func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05004339
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004340 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
4341 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05004342}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004343
Himani Chawla43f95ff2021-06-03 00:24:12 +05304344func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
4345 if dh.pOnuMetricsMgr == nil {
4346 return &extension.SingleGetValueResponse{
4347 Response: &extension.GetValueResponse{
4348 Status: extension.GetValueResponse_ERROR,
4349 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
4350 },
4351 }
4352 }
Himani Chawlaee10b542021-09-20 16:46:40 +05304353 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05304354 return resp
4355}
4356
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +00004357func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
4358
4359 var err error
4360 var pDevOmciCC *cmn.OmciCC
4361 if dh.pOnuOmciDevice == nil {
4362 logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
4363 err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
4364 } else {
4365 pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
4366 if pDevOmciCC == nil {
4367 logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
4368 err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
4369 }
4370 }
4371 if err != nil {
4372 return &extension.SingleGetValueResponse{
4373 Response: &extension.GetValueResponse{
4374 Status: extension.GetValueResponse_ERROR,
4375 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
4376 },
4377 },
4378 err
4379 }
4380 return pDevOmciCC.GetOmciCounters(), nil
4381}
4382
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304383//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004384func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
4385 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00004386 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004387 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004388 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004389}
4390
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004391func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00004392 var pAdapterFsm *cmn.AdapterFsm
4393 //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 +00004394 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004395 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004396 {
mpagenkofbf577d2021-10-12 11:44:33 +00004397 if dh.pOnuOmciDevice != nil {
4398 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
4399 } else {
4400 return true //FSM not active - so there is no activity on omci
4401 }
mpagenkof1fc3862021-02-16 10:09:52 +00004402 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004403 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004404 {
mpagenkofbf577d2021-10-12 11:44:33 +00004405 if dh.pOnuOmciDevice != nil {
4406 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
4407 } else {
4408 return true //FSM not active - so there is no activity on omci
4409 }
mpagenkof1fc3862021-02-16 10:09:52 +00004410 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004411 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004412 {
mpagenkofbf577d2021-10-12 11:44:33 +00004413 if dh.pLockStateFsm != nil {
4414 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
4415 } else {
4416 return true //FSM not active - so there is no activity on omci
4417 }
mpagenkof1fc3862021-02-16 10:09:52 +00004418 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004419 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004420 {
mpagenkofbf577d2021-10-12 11:44:33 +00004421 if dh.pUnlockStateFsm != nil {
4422 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
4423 } else {
4424 return true //FSM not active - so there is no activity on omci
4425 }
mpagenkof1fc3862021-02-16 10:09:52 +00004426 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004427 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004428 {
mpagenkofbf577d2021-10-12 11:44:33 +00004429 if dh.pOnuMetricsMgr != nil {
4430 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00004431 } else {
4432 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004433 }
4434 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004435 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00004436 {
4437 dh.lockUpgradeFsm.RLock()
4438 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00004439 if dh.pOnuUpradeFsm != nil {
4440 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
4441 } else {
4442 return true //FSM not active - so there is no activity on omci
4443 }
mpagenko80622a52021-02-09 16:53:23 +00004444 }
mpagenkof1fc3862021-02-16 10:09:52 +00004445 default:
4446 {
4447 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004448 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00004449 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004450 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004451 }
mpagenkofbf577d2021-10-12 11:44:33 +00004452 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
4453 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
4454 }
4455 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004456}
4457
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004458func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
4459 for _, v := range dh.pOnuTP.PAniConfigFsm {
4460 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004461 return false
4462 }
4463 }
4464 return true
4465}
4466
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304467//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004468func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004469 dh.lockVlanConfig.RLock()
4470 defer dh.lockVlanConfig.RUnlock()
4471 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004472 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004473 return false
4474 }
4475 }
4476 return true //FSM not active - so there is no activity on omci
4477}
4478
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304479//nolint:unparam
mpagenkof1fc3862021-02-16 10:09:52 +00004480func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
4481 dh.lockVlanConfig.RLock()
4482 defer dh.lockVlanConfig.RUnlock()
4483 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004484 if v.PAdaptFsm.PFsm != nil {
4485 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004486 return true //there is at least one VLAN FSM with some active configuration
4487 }
4488 }
4489 }
4490 return false //there is no VLAN FSM with some active configuration
4491}
4492
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004493func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004494 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
4495 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
4496 return false
4497 }
4498 }
4499 // a further check is done to identify, if at least some data traffic related configuration exists
4500 // 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])
4501 return dh.checkUserServiceExists(ctx)
4502}
4503
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004504func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304505 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 +00004506 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004507 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004508 // TODO: fatal error reset ONU, delete deviceHandler!
4509 return
4510 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004511 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
4512 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004513}
4514
4515func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
4516 dh.mutexCollectorFlag.Lock()
4517 dh.collectorIsRunning = flagValue
4518 dh.mutexCollectorFlag.Unlock()
4519}
4520
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004521func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004522 dh.mutexCollectorFlag.RLock()
4523 flagValue := dh.collectorIsRunning
4524 dh.mutexCollectorFlag.RUnlock()
4525 return flagValue
4526}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304527
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304528func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
4529 dh.mutextAlarmManagerFlag.Lock()
4530 dh.alarmManagerIsRunning = flagValue
4531 dh.mutextAlarmManagerFlag.Unlock()
4532}
4533
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004534func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304535 dh.mutextAlarmManagerFlag.RLock()
4536 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004537 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304538 dh.mutextAlarmManagerFlag.RUnlock()
4539 return flagValue
4540}
4541
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004542func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004543 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
bseeniva596a5222026-01-23 19:26:11 +05304544 dh.RLockMutexDeletionInProgressFlag()
4545 if dh.GetDeletionInProgress() {
4546 logger.Warnw(ctx, "Device deletion in progress - avoid starting alarm manager", log.Fields{"device-id": dh.DeviceID})
4547 dh.RUnlockMutexDeletionInProgressFlag()
4548 return
4549 }
4550 // Set alarmManagerIsRunning flag to true while still holding deviceDeletionFlag lock,
4551 // to avoid potential race condition where resetFsm from DeleteDevice might avoid stopping the alarm manager if this flag is not yet set
4552 dh.setAlarmManagerIsRunning(true)
4553
4554 dh.RUnlockMutexDeletionInProgressFlag()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304555
4556 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004557 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304558 if stop := <-dh.stopAlarmManager; stop {
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05304559 logger.Debugw(ctx, "stopping-alarm-manager-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawlad3dac422021-03-13 02:31:31 +05304560 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004561 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
4562 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05304563 }
Himani Chawlad3dac422021-03-13 02:31:31 +05304564 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004565 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
4566 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05304567 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304568 }
4569}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00004570
Girish Gowdrae95687a2021-09-08 16:30:58 -07004571func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
4572 dh.mutexFlowMonitoringRoutineFlag.Lock()
4573 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004574 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004575 dh.isFlowMonitoringRoutineActive[uniID] = flag
4576}
4577
4578func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
4579 dh.mutexFlowMonitoringRoutineFlag.RLock()
4580 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
4581 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004582 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Sridhar Ravindrae9a8bcc2024-12-06 10:40:54 +05304583 if len(dh.isFlowMonitoringRoutineActive) != 0 {
4584 return dh.isFlowMonitoringRoutineActive[uniID]
4585 }
4586 return false
Girish Gowdrae95687a2021-09-08 16:30:58 -07004587}
4588
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004589func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304590 logger.Info(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004591
Maninder7961d722021-06-16 22:10:28 +05304592 connectStatus := voltha.ConnectStatus_UNREACHABLE
4593 operState := voltha.OperStatus_UNKNOWN
4594
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004595 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004596 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004597 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004598 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004599 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004600 case success := <-dh.chReconcilingFinished:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304601 logger.Info(ctx, "reconciling finished signal received",
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004602 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4603 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4604 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4605 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4606 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4607 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4608 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4609 // However, a later refactoring of the functionality remains unaffected.
4610 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004611 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004612 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304613 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004614 log.Fields{"device-id": dh.DeviceID})
akashreddykb03dde02025-12-02 10:53:18 +05304615 } else if !onuDevEntry.SOnuPersistentData.PersRebootInProgress {
mpagenko2c3f6c52021-11-23 11:22:10 +00004616 onuDevEntry.MutexPersOnuConfig.RLock()
mgoudad611f4c2025-10-30 14:49:27 +05304617 switch onuDevEntry.SOnuPersistentData.PersOperState {
4618 case "up":
Maninderb5187552021-03-23 22:23:42 +05304619 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004620 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4621 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304622 operState = voltha.OperStatus_ACTIVE
4623 } else {
4624 operState = voltha.OperStatus_ACTIVATING
4625 }
4626 }
mgoudad611f4c2025-10-30 14:49:27 +05304627 case "down", "unknown", "":
Maninderb5187552021-03-23 22:23:42 +05304628 operState = voltha.OperStatus_DISCOVERED
4629 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004630 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004631 logger.Debugw(ctx, "Core DeviceStateUpdate",
4632 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304633 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304634 logger.Info(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004635 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004636 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004637 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004638 ConnStatus: connectStatus,
4639 OperStatus: operState,
4640 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304641 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004642 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304643 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004644 } else {
Maninderb5187552021-03-23 22:23:42 +05304645 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004646 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304647
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004648 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304649 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004650 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004651 } else {
4652 onuDevEntry.MutexPersOnuConfig.RLock()
4653 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4654 connectStatus = voltha.ConnectStatus_REACHABLE
4655 }
4656 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304657 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004658 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004659 }
mpagenko101ac942021-11-16 15:01:29 +00004660 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004661 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004662 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004663 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304664
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004665 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304666 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004667 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004668 } else {
4669 onuDevEntry.MutexPersOnuConfig.RLock()
4670 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4671 connectStatus = voltha.ConnectStatus_REACHABLE
4672 }
4673 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304674 }
4675
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004676 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304677
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004678 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004679 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004680 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004681 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004682 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004683
4684 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4685 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4686 } else {
4687 onuDevEntry.MutexReconciledTpInstances.Lock()
mgoudad611f4c2025-10-30 14:49:27 +05304688 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]ia.TechProfileDownloadMessage)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004689 onuDevEntry.MutexReconciledTpInstances.Unlock()
4690 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004691 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004692 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004693 dh.mutexReconcilingFlag.Lock()
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304694 if skipOnuConfig || dh.GetSkipOnuConfigEnabled() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004695 dh.reconciling = cSkipOnuConfigReconciling
4696 } else {
4697 dh.reconciling = cOnuConfigReconciling
4698 }
4699 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004700}
4701
mpagenko101ac942021-11-16 15:01:29 +00004702func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304703 logger.Warn(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004704 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004705 dh.sendChReconcileFinished(success)
4706 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4707 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4708 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004709 } else {
mpagenko101ac942021-11-16 15:01:29 +00004710 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004711 }
4712}
4713
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004714func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004715 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004716 defer dh.mutexReconcilingFlag.RUnlock()
4717 return dh.reconciling != cNoReconciling
4718}
4719
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004720func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004721 dh.mutexReconcilingFlag.RLock()
4722 defer dh.mutexReconcilingFlag.RUnlock()
4723 return dh.reconciling == cSkipOnuConfigReconciling
4724}
4725
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004726func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4727 dh.mutexReconcilingFirstPassFlag.Lock()
4728 dh.reconcilingFirstPass = value
4729 dh.mutexReconcilingFirstPassFlag.Unlock()
4730}
4731
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004732func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4733 dh.mutexReconcilingReasonUpdate.Lock()
4734 dh.reconcilingReasonUpdate = value
4735 dh.mutexReconcilingReasonUpdate.Unlock()
4736}
4737
4738func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4739 dh.mutexReconcilingReasonUpdate.RLock()
4740 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4741 return dh.reconcilingReasonUpdate
4742}
4743
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004744func (dh *deviceHandler) getDeviceReason() uint8 {
4745 dh.mutexDeviceReason.RLock()
4746 value := dh.deviceReason
4747 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004748 return value
4749}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004750
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004751func (dh *deviceHandler) GetDeviceReasonString() string {
4752 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004753}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004754
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004755func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004756 dh.mutexReadyForOmciConfig.Lock()
4757 dh.readyForOmciConfig = flagValue
4758 dh.mutexReadyForOmciConfig.Unlock()
4759}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004760func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004761 dh.mutexReadyForOmciConfig.RLock()
4762 flagValue := dh.readyForOmciConfig
4763 dh.mutexReadyForOmciConfig.RUnlock()
4764 return flagValue
4765}
Maninder7961d722021-06-16 22:10:28 +05304766
4767func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004768 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304769 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004770 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304771 }
4772
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004773 logger.Debugw(ctx, "Core DeviceStateUpdate",
4774 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004775 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004776 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004777 ConnStatus: connectStatus,
4778 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4779 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304780 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004781 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304782 }
4783}
khenaidoo7d3c5582021-08-11 18:09:44 -04004784
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05304785func (dh *deviceHandler) deviceRebootStateUpdate(ctx context.Context, techProfInstLoadFailed bool) {
4786 if techProfInstLoadFailed {
4787 if err := dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, true); err != nil {
4788 logger.Errorw(ctx, "unable to update device reason to core",
4789 log.Fields{"device-id": dh.DeviceID, "Err": err})
4790 }
4791 context := make(map[string]string)
4792 context["device-id"] = dh.DeviceID
4793 context["onu-serial-number"] = dh.device.SerialNumber
4794 context["parent-id"] = dh.parentID
4795
4796 // Send event on flow configuration failure so that corrective action can be triggered from NB
4797 deviceEvent := &voltha.DeviceEvent{
4798 ResourceId: dh.DeviceID,
4799 DeviceEventName: cmn.OnuFlowConfigFailed,
4800 Description: cmn.OnuFlowConfigFailedDesc,
4801 Context: context,
4802 }
4803 logger.Debugw(ctx, "send device event", log.Fields{"deviceEvent": deviceEvent, "device-id": dh.DeviceID})
4804 _ = dh.EventProxy.SendDeviceEvent(ctx, deviceEvent, voltha.EventCategory_EQUIPMENT, voltha.EventSubCategory_ONU, time.Now().Unix())
4805 }
4806}
4807
khenaidoo7d3c5582021-08-11 18:09:44 -04004808/*
4809Helper functions to communicate with Core
4810*/
4811
4812func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4813 cClient, err := dh.coreClient.GetCoreServiceClient()
4814 if err != nil || cClient == nil {
4815 return nil, err
4816 }
4817 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4818 defer cancel()
4819 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
mgoudad611f4c2025-10-30 14:49:27 +05304820 return cClient.GetDevice(subCtx, &common.ID{Id: deviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04004821}
4822
khenaidoo42dcdfd2021-10-19 17:34:12 -04004823func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004824 cClient, err := dh.coreClient.GetCoreServiceClient()
4825 if err != nil || cClient == nil {
4826 return err
4827 }
4828 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4829 defer cancel()
4830 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004831 logger.Debugw(subCtx, "device-updated-in-core",
4832 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004833 return err
4834}
4835
4836func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4837 cClient, err := dh.coreClient.GetCoreServiceClient()
4838 if err != nil || cClient == nil {
4839 return err
4840 }
4841 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4842 defer cancel()
4843 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004844 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4845 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004846 return err
4847}
4848
4849func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4850 cClient, err := dh.coreClient.GetCoreServiceClient()
4851 if err != nil || cClient == nil {
4852 return err
4853 }
4854 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4855 defer cancel()
4856 _, err = cClient.DeviceUpdate(subCtx, device)
4857 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4858 return err
4859}
4860
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004861func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004862 cClient, err := dh.coreClient.GetCoreServiceClient()
4863 if err != nil || cClient == nil {
4864 return err
4865 }
4866 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4867 defer cancel()
4868 _, err = cClient.PortCreated(subCtx, port)
4869 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4870 return err
4871}
4872
khenaidoo42dcdfd2021-10-19 17:34:12 -04004873func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004874 cClient, err := dh.coreClient.GetCoreServiceClient()
4875 if err != nil || cClient == nil {
4876 return err
4877 }
4878 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4879 defer cancel()
4880 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004881 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 -04004882 return err
4883}
4884
khenaidoo42dcdfd2021-10-19 17:34:12 -04004885func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004886 cClient, err := dh.coreClient.GetCoreServiceClient()
4887 if err != nil || cClient == nil {
4888 return err
4889 }
4890 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4891 defer cancel()
4892 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004893 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 -04004894 return err
4895}
4896
4897/*
4898Helper functions to communicate with parent adapter
4899*/
4900
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004901func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4902 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4903
4904 var request = ia.TechProfileInstanceRequestMessage{
4905 DeviceId: dh.DeviceID,
4906 TpInstancePath: aTpPath,
4907 ParentDeviceId: dh.parentID,
4908 ParentPonPort: dh.device.ParentPortNo,
4909 OnuId: dh.device.ProxyAddress.OnuId,
4910 UniId: uint32(aUniID),
4911 }
4912
4913 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004914 if err != nil || pgClient == nil {
4915 return nil, err
4916 }
4917 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4918 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004919 logger.Debugw(subCtx, "get-tech-profile-instance",
4920 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004921 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004922}
4923
Girish Gowdrae95687a2021-09-08 16:30:58 -07004924// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4925// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4926func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4927 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4928 dh.setFlowMonitoringIsRunning(uniID, true)
4929 for {
4930 select {
4931 // block on the channel to receive an incoming flow
4932 // process the flow completely before proceeding to handle the next flow
4933 case flowCb := <-dh.flowCbChan[uniID]:
4934 startTime := time.Now()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304935 logger.Info(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004936 respChan := make(chan error)
4937 if flowCb.addFlow {
4938 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4939 } else {
4940 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4941 }
4942 // Block on response and tunnel it back to the caller
balaji.nagarajan62ac62b2025-09-08 10:49:58 +05304943 select {
4944
4945 case msg := <-respChan:
4946 *flowCb.respChan <- msg
4947 // response sent successfully
4948 logger.Info(flowCb.ctx, "serial-flow-processor--end",
4949 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4950 case <-flowCb.ctx.Done():
4951 logger.Info(flowCb.ctx, "flow handler context cancelled or timed out", log.Fields{"device-id": dh.DeviceID})
4952 // Optionally, you can handle cleanup or logging here
4953 if dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID] != nil && dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID].PAdaptFsm != nil {
4954 pVlanFilterStatemachine := dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID].PAdaptFsm.PFsm
4955 if pVlanFilterStatemachine != nil {
4956
4957 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
4958 logger.Warnw(flowCb.ctx, "UniVlanConfigFsm: can't reset",
4959 log.Fields{"device-id": dh.DeviceID, "err": err})
4960
4961 }
4962
4963 }
4964 }
4965
4966 ctx2 := context.Background()
4967 metadata := flow.GetMetadataFromWriteMetadataAction(ctx2, flowCb.flowItem)
4968 if metadata == 0 {
4969 logger.Warnw(flowCb.ctx, "AniConfigFsm: can't reset,failed to fetch metadata flow: %v",
4970 log.Fields{"device-id": dh.DeviceID, "flows": flowCb.flowItem})
4971 continue
4972 }
4973 TpID := flow.GetTechProfileIDFromWriteMetaData(ctx2, metadata)
4974
4975 if TpID == uint16(0) {
4976 logger.Warnw(flowCb.ctx, "AniConfigFsm: can't reset,failed to fetch techprofileid flow: %v",
4977 log.Fields{"device-id": dh.DeviceID, "flows": flowCb.flowItem})
4978 continue
4979 }
4980 if dh.pOnuTP != nil {
4981 // should always be the case here
4982 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
4983 if dh.pOnuTP.PAniConfigFsm != nil {
4984 uniTP := avcfg.UniTP{
4985 UniID: flowCb.uniPort.UniID,
4986 TpID: uint8(TpID),
4987 }
4988 if dh.pOnuTP.PAniConfigFsm[uniTP] != nil {
4989 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(context.Background())
4990 }
4991 }
4992 }
4993
4994 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07004995 case <-dh.stopFlowMonitoringRoutine[uniID]:
4996 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4997 dh.setFlowMonitoringIsRunning(uniID, false)
4998 return
4999 }
5000 }
5001}
5002
kesavand011d5162021-11-25 19:21:06 +05305003func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
5004 request.ParentDeviceId = dh.GetProxyAddressID()
5005 request.ChildDeviceId = dh.DeviceID
5006 request.ProxyAddress = dh.GetProxyAddress()
5007 request.ConnectStatus = common.ConnectStatus_REACHABLE
5008
5009 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
5010 if err != nil || pgClient == nil {
5011 return err
5012 }
5013 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
5014 defer cancel()
5015 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
5016 _, err = pgClient.ProxyOmciRequests(subCtx, request)
5017 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00005018 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
5019 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05305020 }
5021 return err
5022}
5023
khenaidoo42dcdfd2021-10-19 17:34:12 -04005024func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04005025 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
5026 if err != nil || pgClient == nil {
5027 return err
5028 }
5029 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
5030 defer cancel()
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005031 dh.setOltAvailable(true)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00005032 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04005033 _, err = pgClient.ProxyOmciRequest(subCtx, request)
5034 if err != nil {
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005035 if status.Code(err) == codes.Unavailable {
5036 dh.setOltAvailable(false)
5037 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00005038 logger.Errorw(ctx, "omci-failure",
5039 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005040 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress, "oltAvailable": dh.IsOltAvailable})
khenaidoo7d3c5582021-08-11 18:09:44 -04005041 }
5042 return err
5043}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005044
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005045func (dh *deviceHandler) CheckAvailableOnuCapabilities(ctx context.Context, pDevEntry *mib.OnuDeviceEntry, tpInst tech_profile.TechProfileInstance) error {
5046 // Check if there are additional TCONT instances necessary/available
5047 pDevEntry.MutexPersOnuConfig.Lock()
5048 if _, ok := pDevEntry.SOnuPersistentData.PersTcontMap[uint16(tpInst.UsScheduler.AllocId)]; !ok {
5049 numberOfTcontMapEntries := len(pDevEntry.SOnuPersistentData.PersTcontMap)
5050 pDevEntry.MutexPersOnuConfig.Unlock()
5051 numberOfTcontDbInsts := pDevEntry.GetOnuDB().GetNumberOfInst(me.TContClassID)
5052 logger.Debugw(ctx, "checking available TCONT instances",
5053 log.Fields{"device-id": dh.DeviceID, "numberOfTcontMapEntries": numberOfTcontMapEntries, "numberOfTcontDbInsts": numberOfTcontDbInsts})
5054 if numberOfTcontMapEntries >= numberOfTcontDbInsts {
5055 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of TCONT instances: send ONU device event!",
5056 log.Fields{"device-id": dh.device.Id})
5057 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingTcont, cmn.OnuConfigFailureMissingTcontDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305058 return fmt.Errorf("configuration exceeds ONU capabilities - running out of TCONT instances: device-id: %s", dh.DeviceID)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005059 }
5060 } else {
5061 pDevEntry.MutexPersOnuConfig.Unlock()
5062 }
5063 // Check if there are enough PrioQueue instances available
5064 if dh.pOnuTP != nil {
5065 var numberOfUsPrioQueueDbInsts int
5066
5067 queueInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(ctx, me.PriorityQueueClassID)
5068 for _, mgmtEntityID := range queueInstKeys {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305069 if mgmtEntityID >= 0x8000 {
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005070 numberOfUsPrioQueueDbInsts++
5071 }
5072 }
5073 // Check if there is an upstream PriorityQueue instance available for each Gem port
5074 numberOfConfiguredGemPorts := dh.pOnuTP.GetNumberOfConfiguredUsGemPorts(ctx)
5075 logger.Debugw(ctx, "checking available upstream PriorityQueue instances",
5076 log.Fields{"device-id": dh.DeviceID,
5077 "numberOfConfiguredGemPorts": numberOfConfiguredGemPorts,
5078 "tpInst.NumGemPorts": tpInst.NumGemPorts,
5079 "numberOfUsPrioQueueDbInsts": numberOfUsPrioQueueDbInsts})
5080
5081 if numberOfConfiguredGemPorts+int(tpInst.NumGemPorts) > numberOfUsPrioQueueDbInsts {
5082 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: send ONU device event!",
5083 log.Fields{"device-id": dh.device.Id})
5084 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingUsPriorityQueue, cmn.OnuConfigFailureMissingUsPriorityQueueDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305085 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 +00005086 }
5087 // Downstream PrioQueue instances are evaluated in accordance with ONU MIB upload data in function UniPonAniConfigFsm::prepareAndEnterConfigState().
5088 // In case of missing downstream PrioQueues the attribute "Priority queue pointer for downstream" of ME "GEM port network CTP" will be set to "0",
5089 // which then alternatively activates the queuing mechanisms of the ONU (refer to Rec. ITU-T G.988 chapter 9.2.3).
5090 } else {
5091 logger.Warnw(ctx, "onuTechProf instance not set up - check for PriorityQueue instances skipped!",
5092 log.Fields{"device-id": dh.DeviceID})
5093 }
5094 return nil
5095}
5096
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005097// GetDeviceID - TODO: add comment
5098func (dh *deviceHandler) GetDeviceID() string {
5099 return dh.DeviceID
5100}
5101
5102// GetProxyAddressID - TODO: add comment
5103func (dh *deviceHandler) GetProxyAddressID() string {
5104 return dh.device.ProxyAddress.GetDeviceId()
5105}
5106
5107// GetProxyAddressType - TODO: add comment
5108func (dh *deviceHandler) GetProxyAddressType() string {
5109 return dh.device.ProxyAddress.GetDeviceType()
5110}
5111
5112// GetProxyAddress - TODO: add comment
5113func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
5114 return dh.device.ProxyAddress
5115}
5116
5117// GetEventProxy - TODO: add comment
5118func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
5119 return dh.EventProxy
5120}
5121
5122// GetOmciTimeout - TODO: add comment
5123func (dh *deviceHandler) GetOmciTimeout() int {
5124 return dh.pOpenOnuAc.omciTimeout
5125}
5126
5127// GetAlarmAuditInterval - TODO: add comment
5128func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
5129 return dh.pOpenOnuAc.alarmAuditInterval
5130}
5131
5132// GetDlToOnuTimeout4M - TODO: add comment
5133func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
5134 return dh.pOpenOnuAc.dlToOnuTimeout4M
5135}
5136
5137// GetUniEntityMap - TODO: add comment
5138func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
5139 return &dh.uniEntityMap
5140}
5141
5142// GetPonPortNumber - TODO: add comment
5143func (dh *deviceHandler) GetPonPortNumber() *uint32 {
5144 return &dh.ponPortNumber
5145}
5146
5147// GetUniVlanConfigFsm - TODO: add comment
5148func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00005149 dh.lockVlanConfig.RLock()
5150 value := dh.UniVlanConfigFsmMap[uniID]
5151 dh.lockVlanConfig.RUnlock()
5152 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005153}
5154
5155// GetOnuAlarmManager - TODO: add comment
5156func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
5157 return dh.pAlarmMgr
5158}
5159
5160// GetOnuMetricsManager - TODO: add comment
5161func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
5162 return dh.pOnuMetricsMgr
5163}
5164
5165// GetOnuTP - TODO: add comment
5166func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
5167 return dh.pOnuTP
5168}
5169
5170// GetBackendPathPrefix - TODO: add comment
5171func (dh *deviceHandler) GetBackendPathPrefix() string {
5172 return dh.pOpenOnuAc.cm.Backend.PathPrefix
5173}
5174
5175// GetOnuIndication - TODO: add comment
mgoudad611f4c2025-10-30 14:49:27 +05305176func (dh *deviceHandler) GetOnuIndication() *oop.OnuIndication {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005177 return dh.pOnuIndication
5178}
5179
5180// RLockMutexDeletionInProgressFlag - TODO: add comment
5181func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
5182 dh.mutexDeletionInProgressFlag.RLock()
5183}
5184
5185// RUnlockMutexDeletionInProgressFlag - TODO: add comment
5186func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
5187 dh.mutexDeletionInProgressFlag.RUnlock()
5188}
5189
5190// GetDeletionInProgress - TODO: add comment
5191func (dh *deviceHandler) GetDeletionInProgress() bool {
5192 return dh.deletionInProgress
5193}
5194
5195// GetPmConfigs - TODO: add comment
5196func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
5197 return dh.pmConfigs
5198}
5199
5200// GetDeviceType - TODO: add comment
5201func (dh *deviceHandler) GetDeviceType() string {
5202 return dh.DeviceType
5203}
5204
5205// GetLogicalDeviceID - TODO: add comment
5206func (dh *deviceHandler) GetLogicalDeviceID() string {
5207 return dh.logicalDeviceID
5208}
5209
5210// GetDevice - TODO: add comment
5211func (dh *deviceHandler) GetDevice() *voltha.Device {
5212 return dh.device
5213}
5214
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005215func (dh *deviceHandler) setOltAvailable(value bool) {
5216 dh.mutexOltAvailable.Lock()
5217 dh.oltAvailable = value
5218 dh.mutexOltAvailable.Unlock()
5219}
5220
5221// IsOltAvailable - TODO: add comment
5222func (dh *deviceHandler) IsOltAvailable() bool {
5223 dh.mutexOltAvailable.RLock()
5224 defer dh.mutexOltAvailable.RUnlock()
5225 return dh.oltAvailable
5226}
5227
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005228// GetMetricsEnabled - TODO: add comment
5229func (dh *deviceHandler) GetMetricsEnabled() bool {
5230 return dh.pOpenOnuAc.MetricsEnabled
5231}
5232
Holger Hildebrandtc572e622022-06-22 09:19:17 +00005233// GetExtendedOmciSupportEnabled - TODO: add comment
5234func (dh *deviceHandler) GetExtendedOmciSupportEnabled() bool {
5235 return dh.pOpenOnuAc.ExtendedOmciSupportEnabled
5236}
5237
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05305238// GetExtendedOmciSupportEnabled - TODO: add comment
5239func (dh *deviceHandler) GetSkipOnuConfigEnabled() bool {
5240 return dh.pOpenOnuAc.skipOnuConfig
5241}
5242
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05305243func (dh *deviceHandler) GetDeviceTechProfOnReboot() bool {
5244 return dh.pOpenOnuAc.CheckDeviceTechProfOnReboot
5245}
5246
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005247// InitPmConfigs - TODO: add comment
5248func (dh *deviceHandler) InitPmConfigs() {
5249 dh.pmConfigs = &voltha.PmConfigs{}
5250}
5251
5252// GetUniPortMask - TODO: add comment
5253func (dh *deviceHandler) GetUniPortMask() int {
5254 return dh.pOpenOnuAc.config.UniPortMask
5255}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00005256
5257func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
5258 tpPathFound := false
5259 for _, tpPath := range aTpPathMap {
5260 if tpPath != "" {
5261 tpPathFound = true
5262 }
5263 }
5264 return tpPathFound
5265}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005266
praneeth nalmas5a0a5502022-12-23 15:57:00 +05305267func (dh *deviceHandler) getOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
5268 resp := dh.GetOnuAlarmManager().GetOnuActiveAlarms(ctx)
5269 logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
5270 return resp
5271}
5272
Akash Reddy Kankanalac28f0e22025-06-16 11:00:55 +05305273// getONUGEMStatsInfo - Get the GEM PM history data of the request ONT device
5274func (dh *deviceHandler) getONUGEMStatsInfo(ctx context.Context) *extension.SingleGetValueResponse {
5275 resp := dh.pOnuMetricsMgr.GetONUGEMCounters(ctx)
pnalmas6d6b7d72025-10-23 16:34:22 +05305276 logger.Debugw(ctx, "Received response from ONU Metrics Manager for GEM Stats", log.Fields{"device-id": dh.DeviceID})
5277 return resp
5278}
5279
5280// getOnuFECStats - Get the GEM PM history data of the request ONT device
5281func (dh *deviceHandler) getOnuFECStats(ctx context.Context) *extension.SingleGetValueResponse {
5282 resp := dh.pOnuMetricsMgr.GetONUFECCounters(ctx)
5283 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 +05305284 return resp
5285}
5286
Praneeth Kumar Nalmasaacc6122024-04-09 22:55:49 +05305287func (dh *deviceHandler) GetDeviceDeleteCommChan(ctx context.Context) chan bool {
5288 return dh.deviceDeleteCommChan
5289}
5290
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005291// PrepareForGarbageCollection - remove references to prepare for garbage collection
5292func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
5293 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
5294
5295 // Note: This function must be called as a goroutine to prevent blocking of further processing!
5296 // first let the objects rest for some time to give all asynchronously started
5297 // cleanup routines a chance to come to an end
Holger Hildebrandt12609a12022-03-25 13:23:25 +00005298 time.Sleep(2 * time.Second)
5299
Holger Hildebrandt12609a12022-03-25 13:23:25 +00005300 time.Sleep(3 * time.Second)
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005301
5302 if dh.pOnuTP != nil {
5303 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
5304 }
5305 if dh.pOnuMetricsMgr != nil {
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00005306 logger.Debugw(ctx, "preparation of garbage collection is done under control of pm fsm - wait for completion",
5307 log.Fields{"device-id": aDeviceID})
Girish Gowdraabcceb12022-04-13 23:35:22 -07005308 select {
5309 case <-dh.pOnuMetricsMgr.GarbageCollectionComplete:
5310 logger.Debugw(ctx, "pm fsm shut down and garbage collection complete", log.Fields{"deviceID": aDeviceID})
5311 case <-time.After(pmmgr.MaxTimeForPmFsmShutDown * time.Second):
5312 logger.Errorw(ctx, "fsm did not shut down in time", log.Fields{"deviceID": aDeviceID})
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00005313 default:
Girish Gowdraabcceb12022-04-13 23:35:22 -07005314 }
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005315 }
5316 if dh.pAlarmMgr != nil {
5317 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
5318 }
5319 if dh.pSelfTestHdlr != nil {
5320 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
5321 }
5322 if dh.pLockStateFsm != nil {
5323 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5324 }
5325 if dh.pUnlockStateFsm != nil {
5326 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5327 }
5328 if dh.pOnuUpradeFsm != nil {
5329 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5330 }
5331 if dh.pOnuOmciDevice != nil {
5332 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
5333 }
5334 for k, v := range dh.UniVlanConfigFsmMap {
5335 v.PrepareForGarbageCollection(ctx, aDeviceID)
5336 delete(dh.UniVlanConfigFsmMap, k)
5337 }
nikesh.krishnan1249be92023-11-27 04:20:12 +05305338 dh.pOnuIndication = nil
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005339 dh.pOnuOmciDevice = nil
bseeniva0cbc62a2026-01-23 19:08:36 +05305340 dh.lockDevice.Lock()
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005341 dh.pOnuTP = nil
bseeniva0cbc62a2026-01-23 19:08:36 +05305342 dh.lockDevice.Unlock()
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005343 dh.pOnuMetricsMgr = nil
5344 dh.pAlarmMgr = nil
5345 dh.pSelfTestHdlr = nil
5346 dh.pLockStateFsm = nil
5347 dh.pUnlockStateFsm = nil
5348 dh.pOnuUpradeFsm = nil
5349}